try块中的java代码被忽略,为什么?
我是编程新手,一直试图通过编写一个简单的程序来学习Java的基础知识,该程序将对某些文本应用Caesar变换。我已经能够做到这一点,到目前为止,我的代码所做的是:
- 询问用户希望文本移动多少单位李>
- 提示用户输入一些文本李>
- 应用Caesar移位的单位数并打印结果李>
以下是工作代码:
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块包含声明整数“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);
}
}
那么,为什么这一小小的变化突然阻止了“转变”的宣布呢
# 1 楼答案
变量仅限于其声明的范围。有关更多信息,请参见this nice little tutorial about variable scope in Java(如果您想了解技术,请参见JLS section 6.3,在您的案例中,以“局部变量声明的范围”开头的行是相关的)
作用域的最简单解释是它们在其中声明的
{ ... }
对就你而言:
变量
shift
在该try
块的{ ... }
外不可见。您必须在更高的范围内声明它,例如,作为方法的局部变量。但是,在try
块的情况下,如果您只是将声明移到外部,仍然会遇到“变量可能未初始化使用”警告,因为在这种情况下:在
nextInt()
引发异常的代码路径仍然可以保持shift
未初始化。在这种情况下,要解决这个问题,一个选项是对其进行初始化:另一个选项是确保即使引发异常也能获得值:
第三种选择是以这样的方式构造代码,即在抛出异常时,不会尝试使用
shift
,尽管这不太适合您的示例(但为了完整性):第四个选项是以这样的方式构造代码,即
shift
在try
块之外不需要shift
:# 2 楼答案
在Java中,每当你在一个块中声明一个变量时,你就是在对这个变量进行我们所说的局部声明。这意味着该变量只能在声明它的块中看到。在本例中,由于您在
try
块内声明了shift
,因此从try
块外的任何地方都看不到它。要解决这个问题,只需在try
块之外声明它,如下所示:您可以在这里了解有关Java中声明范围的更多信息:https://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.3
# 3 楼答案
在区块外声明移位。问题的出现是因为移位的作用域仅限于try。将其更改为:
# 4 楼答案
问题是,当您在try块中声明变量时,该变量的作用域就是try块。一旦try块完成执行,try块中声明的所有变量都将被删除。您需要将声明移到try块之外。像这样:
希望这有帮助:)