我正在玩学习目的的异常,我有一个问题。请参阅以下代码:
public static void main(String[] args) {
System.out.print(getNumber());
}
public static double getNumber() {
double number =10;
try {
String [] students = {"nick","george"};
System.out.println(students[5]);
}
catch (ArrayIndexOutOfBoundsException ex ) {
System.out.println("In catch block "+ number);
return number;
}
finally {
number +=10;
System.out.println("The value is now "+ number);
}
System.out.println("hiiiii");
return number;
}
为什么在这种情况下main方法的输出将为10,为什么如果我运行相同的示例并返回一个对象,该值将被更改?
public static void main(String[] args) {
System.out.println("In main is "+getStringBuffer());
}
public static StringBuffer getStringBuffer() {
StringBuffer number = new StringBuffer("10");
try {
String [] names= {"george" ,"nick"};
System.out.println(names[5]);
}
catch (ArrayIndexOutOfBoundsException ex1) {
System.out.println("In catch block "+ number);
return number;
}
finally {
number.reverse();
System.out.println("In finally is "+ number);
}
System.out.println("hiiii");
return number;
}
答案 0 :(得分:3)
因为在第一个例子中,你返回一个原语,它的返回值已经在栈上,并且不能被finally块改变。
在第二个示例中,您将返回一个引用变量,并且它指向的值可以由finally块更改。
答案 1 :(得分:3)
方法返回的值设置为它遇到的return
语句。所以
return number;
不表示“记住您要返回number
变量”,这意味着“评估number
变量,并记住要使用的结果值它作为返回值“。稍后更改number
变量的内容(在finally
块中)对方法返回的值没有影响,该值已经确定。
我们怎么知道这个?因为return
必须评估表达式(每§14.17 of the JLS)。例如,假设你有
return number + 5;
...您不希望获得25
,因为您有10
,点击return
语句,然后在10
中添加了另一个finally
}阻止,然后表达式添加5
更多,对吗? return
评估表达式并记住值作为方法的返回值。
在您给出的对象示例中,finally
块中未更改返回的值。它仍然只是对象的引用。您正在更改正在返回其引用的对象的状态,但该引用未被更改。如果你更换了
number.reverse();
与
number = new StringBuffer();
...您会看到与double
完全相同的行为,因为在这种情况下,您正在更改{{1}中保留的值 (对象的引用),就像使用number
一样。
答案 2 :(得分:2)
catch
块在finally
块之前运行。在代码的原始版本中,当return
发生时,该变量的值仍为10,因此返回的是该值。
在代码的第二个版本中,您将返回StringBuffer
,但您正在编辑StringBuffer
的内容。因此,虽然只返回一个StringBuffer
,但是当调用方法看到返回的对象时,它已经被更新了。
另一种看待这种情况的方法是,在第二种情况下,返回的东西是对一个坐在堆中的对象的引用;但在第一种情况下,你实际上是在返回一个值,而不是一个引用。
答案 3 :(得分:0)
第一个问题:为什么在这种情况下main方法的输出将是10.
因为您试图访问不可用的值。
原因:String [] students = {“nick”,“george”};
herestudents数组大小为2,您试图访问第5个元素,如下所示:
System.out.println(students[5]);
通过调用上面的语句java throws ArrayIndexOutOfBoundsException
。
当您捕获ArrayIndexOutOfBoundsException
异常时,将执行catch块内的所有语句。
在这里打印数字值如下:
System.out.println("In catch block "+ number);
将打印10.