【问题标题】:Return primitive data type from a catch block in java [duplicate]从java中的catch块返回原始数据类型[重复]
【发布时间】:2013-11-10 18:48:39
【问题描述】:

出于学习目的,我正在研究例外情况,我有一个问题。请看下面的代码:

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

为什么在这种情况下主方法的输出是 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;
}

【问题讨论】:

  • "...为什么如果我运行相同的示例并返回一个对象,值将被更改?" 嗯?你能告诉我们你的意思吗?什么样的物体?
  • @T.J.Crowder 这就是我的意思..请立即查看已编辑的问题
  • @notArefill:啊,因为你改变的是对象的状态,而不是返回的值。

标签: java


【解决方案1】:

该方法返回的值设置为它遇到的return 语句。所以

return number;

的意思是“记住你要返回 number 变量”,它的意思是“计算 number 变量,并记住结果值将其用作返回值价值”。稍后更改number 变量的内容(在finally 块中)对方法返回的值没有影响,这已经确定了。

我们怎么知道这个?因为return 必须计算表达式(每个§14.17 of the JLS)。例如,假设你有

return number + 5;

...你不会期望得到25,因为你有10,点击return 语句,然后在finally 块中添加另一个10,然后表达式添加@987654335 @更多,对吧? return 计算表达式并记住 value 作为方法的返回值。

在您给出的对象示例中,返回的 finally 块中没有被更改。它仍然只是对对象的引用。您正在更改正在返回其引用的对象的 state,但引用并未被更改。如果你换了

number.reverse();

number = new StringBuffer();

...您会看到与 double 完全相同的行为,因为在这种情况下,您正在更改 number 中保存的 (参考到对象),就像你对 number += 10; 所做的那样。

【讨论】:

    【解决方案2】:

    因为在第一个示例中,您正在返回一个原语,并且它的返回值已经在堆栈上,并且不能被 finally 块更改。

    在第二个例子中,你返回一个引用变量,它指向的值可以被 finally 块改变。

    【讨论】:

      【解决方案3】:

      catch 块在 finally 块之前运行。在代码的原始版本中,当return 出现时,该变量的值仍然是10,所以这就是返回的值。

      在代码的第二个版本中,您返回的是 StringBuffer,但您正在编辑该 StringBuffer 的内容。因此,虽然只有一个 StringBuffer,您要返回它,但当调用方法看到返回的对象时,它已经被更新了。

      另一种看待这一点的方式是,在第二种情况下,返回的东西是对位于堆中的对象的引用;但在第一种情况下,您实际上返回的是一个值,而不是一个引用。

      【讨论】:

        【解决方案4】:

        第一个问题:为什么在这种情况下 main 方法的输出是 10。

        因为您试图访问不可用的值。

        原因:字符串 [] 学生 = {"nick","george"};

        herestudents 数组大小为 2,您正在尝试访问第 5 个元素,如下所示:

          System.out.println(students[5]);  
        

        通过调用上面的语句 java throws ArrayIndexOutOfBoundsException.

        当您捕获 ArrayIndexOutOfBoundsException 异常时,将执行 catch 块中的所有语句。

        这里你打印的数值如下:

        System.out.println("In catch block "+ number); 
        

        这将打印10.的数字

        【讨论】:

        • 我明白,我的问题是为什么在第一种情况下我不能改变值,为什么当我有一个对象时我可以。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-10
        • 2013-11-22
        相关资源
        最近更新 更多