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

时间:2014-11-23 21:29:06

标签: java try-catch

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

  1. 询问用户他们想要移动文本的单位数。
  2. 提示用户输入一些文字。
  3. 按照许多单位应用凯撒移位并打印结果。
  4. 以下是工作代码:

    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);
        }
        }
    

    此代码的问题在于,当要求用户输入整数时,如果输入任何其他内容,则会出现异常。我认为这是一个学习处理异常的好地方,并且已经提到this guide关于如何使用try-catch块来实现此目的。

    我遇到的问题是代码(下面)似乎完全忽略了我的try块。我认为这是因为我的try块包含整数&#34; shift&#34;宣布,当我向下滚动到&#34; shift&#34;实际上在我的代码中使用我得到一个警告说&#34; shift无法解析为变量&#34;它无法编译。

    这里是导致问题的代码,唯一的区别是我在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);
        }
        }
    

    那么为什么这一小小的变化突然停止了#34;转移&#34;从被宣布?

4 个答案:

答案 0 :(得分:6)

变量仅限于声明它们的范围。有关详细信息,请参阅this nice little tutorial about variable scope in Java(如果您想获得技术,请参阅JLS section 6.3,在您的情况下,请参阅以“范围”开头的行本地变量声明“是相关的”。

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

在你的情况下:

...
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,尽管这不适合您的示例(但是,为了完整性): / p>

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

答案 1 :(得分:3)

在块之外声明移位。问题正在发生,因为转移只在内部尝试范围。改为:

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

答案 2 :(得分:1)

问题是当你在try块中声明一个变量时,该变量的范围就是try块。一旦try块完成执行,try块内声明的所有变量都将被删除。您需要在try块之外移动声明。像这样:

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

希望这会有所帮助:)

答案 3 :(得分:0)

在Java中,每当你在一个块中声明一个变量时,你就会做出我们称之为该变量的本地声明。这意味着变量只能在您声明它的块中可见。在这种情况下,由于您在shift块中声明了try,因此在try之外的任何位置都无法显示。您可以解决的问题只是在try块之外声明它,如下所示:

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

您可以在此处了解有关Java声明范围的更多信息:https://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.3