try块中的代码被忽略,为什么?

用户名

我是编程的新手,并且一直在尝试通过编写一个简单的将Caesar转换应用于某些文本的程序来学习Java的基础知识。我已经能够做到这一点,到目前为止,我的代码所做的是:

  1. 询问用户他们希望将文本移动多少个单位。
  2. 提示用户输入一些文本。
  3. 应用多个单位进行凯撒平移并打印结果。

这是工作代码:

import java.util.Scanner;
class Shift{

public static void main(String[] args){

    //This will scan for user input.
    Scanner sc = new Scanner(System.in);
    System.out.print("Shift by this many characters (0-25): ");
    int shift = sc.nextInt();
    sc.nextLine();//Skips over the whitespace after the integer
    System.out.print("Enter Text: ");
    String input = sc.nextLine();
    sc.close();

    //Initialise a character array containing every letter in the alphabet. 
    char[] alphabetArray = {'a','b','c','d','e','f','g','h','i','j','k','l','m',
                            'n','o','p','q','r','s','t','u','v','w','x','y','z'};
    char[] alphabetArrayCaps = {'A','B','C','D','E','F','G','H','I','J','K','L','M',
                                'N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};

    //Initialise the two variables that will be used in the next step.
    char[] constantArray = input.toCharArray();
    char[] output = input.toCharArray();

    //Implement a Caesar shift by the given number of units.
    for (int i=0; i < constantArray.length; i++){ //cycles through the user input character by character
        for (int j=0; j <= 25; j++){ //cycles through the alphabet
            if (constantArray[i] == alphabetArray[j]){
                    output[i] = alphabetArray[(j+shift)%26];
            }
            else if (constantArray[i] == alphabetArrayCaps[j]){
                        output[i] = alphabetArrayCaps[(j+shift)%26];
            }
        }
    }
    System.out.println(output);
    }
    }

此代码的问题在于,当要求用户输入整数时,如果输入了其他任何内容,则会出现异常。我认为这将是学习处理异常的好地方,并且一直在参考本指南中有关如何为此使用try-catch块的信息。

我遇到的问题是代码(如下)似乎完全忽略了我的try块。我认为这是因为我的try块包含声明整数“ shift”的行,并且当我向下滚动到我的代码中实际使用“ shift”的位置时,我得到一条警告,指出“ shift不能解析为变量”,则无法编译。

这是导致问题的代码,唯一的区别是我已经在try块中加上了一行,并在其后添加了catch块,该块应该显示一条错误消息(尽管我还没有得到编译的代码,所以还没有还没有机会玩这个游戏,看看它实际上是做什么的)。

import java.util.Scanner;
class Shift{

public static void main(String[] args){

    //This will scan for user input.
    Scanner sc = new Scanner(System.in);
    System.out.print("Shift by this many characters (0-25): ");

    try {
        int shift = sc.nextInt();
    }
    catch (java.util.InputMismatchException e){
        System.err.println("InputMismatchException: " + e.getMessage());                        
    }

    sc.nextLine();//Skips over the whitespace after the integer
    System.out.print("Enter Text: ");
    String input = sc.nextLine();
    sc.close();

    //Initialise a character array containing every letter in the alphabet. 
    char[] alphabetArray = {'a','b','c','d','e','f','g','h','i','j','k','l','m',
                            'n','o','p','q','r','s','t','u','v','w','x','y','z'};
    char[] alphabetArrayCaps = {'A','B','C','D','E','F','G','H','I','J','K','L','M',
                                'N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};

    //Initialise the two variables that will be used in the next step.
    char[] constantArray = input.toCharArray();
    char[] output = input.toCharArray();

    //Implement a Caesar shift by the given number of units.
    for (int i=0; i < constantArray.length; i++){ //cycles through the user input character by character
        for (int j=0; j <= 25; j++){ //cycles through the alphabet
            if (constantArray[i] == alphabetArray[j]){
                    output[i] = alphabetArray[(j+shift)%26];
            }
            else if (constantArray[i] == alphabetArrayCaps[j]){
                        output[i] = alphabetArrayCaps[(j+shift)%26];
            }
        }
    }
    System.out.println(output);
    }
    }

那么,为什么这一小小的变化突然阻止了“转变”的宣布呢?

杰森c

变量仅限于声明它们的作用域。有关更多信息,请参见关于Java中变量作用域的这个不错的小教程(或者,如果您想获得技术方面的知识,请参阅JLS第6.3节,在这种情况下,以“ The scope of ...本地变量声明”)。

范围的最简单解释{ ... }是声明它们对。

在您的情况下:

...
try {
    int shift = sc.nextInt();
} ...

该变量shift{ ... }try块的外部不可见您将不得不在更高的范围内声明它,例如,作为方法的局部变量。但是,在try的情况下,如果仅将声明移到外面,您仍然会遇到“可能未使用变量的变量”警告,因为在这种情况下:

int shift;

try {
    shift = sc.nextInt();
} catch (...) {
    ...
}

nextInt()引发异常的代码路径仍然可以保持shift未初始化状态。在这种情况下,要解决此问题,一种方法是对其进行初始化:

int shift = 0;

try {
    shift = sc.nextInt();
} catch (...) {
    ...
}

另一个选择是确保即使抛出异常也可以获取值:

int shift;

try {
    shift = sc.nextInt();
} catch (...) {
    shift = 0;
    ...
}

第三种选择是,以这样一种方式来构造代码,即shift在引发异常时也不会尝试使用它,尽管这并不完全适合您的示例(但出于完整性考虑):

int shift;

try {
    shift = sc.nextInt();
} catch (Exception x) {
    throw x;
}

// shift can never be used uninitialized here

第四种选择是,以shift无需在try使用的方式来构造代码

try {
    int shift = sc.nextInt();
    // do everything that needs to be done with shift here
} catch (...) {
    ...
}

// shift is unneeded here

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么我的代码中的 if 语句被忽略?

在try块中返回的伪代码是什么?

为什么EntityFramework代码首先忽略代码中设置的键值

为什么在 try 块中没有捕获 500 错误?

为什么不能在try / catch块中访问变量?

为什么我不能使用try / except块“忽略”此ConnectionError?

为什么此代码中需要“最终”块

为什么折叠的代码块在PhpStorm中“自动”展开

为什么静态块中的代码执行多次?

为什么在try块中使用return仍要执行finally块中的语句

为什么需要openFileOutput的try catch块?

为什么在许多代码中写成“ if try catch”?

为什么在添加else块时忽略了else块?

为什么不应将新File()放入try块,而应将新FileReader(“ input.txt”)放在try块中?

为什么C预处理程序不会忽略其跳过的块中的无效指令?

最终总是在try块中的return之前运行,那么为什么finally块中的更新不影响try块返回的变量的值?

为什么try块在Kotlin中不返回lambda表达式中的值?

为什么没有代码的CSS块?

代码为什么不输入每个块?

为什么这些代码块的行为不同?

为什么允许使用独立代码块?

为什么我的代码在代码块下而不在VS Studio中运行

为什么在代码块中执行代码时会跳过输入用户输入的行?

为什么在这个“try...except”块中没有捕获/处理错误?

为什么不将每个块都包装在“ try”-“ catch”中?

为什么在try块中重新声明函数标识符会引发SyntaxError?

为什么引发异常的此方法在调用时不必放在try catch块中?

为什么我不能在 php 的 try 块中定义函数之前调用它

RAII失败-为什么此C ++代码泄漏?-在try块中放入ctor可以防止dtor