如果在方法中传递,最终变量如何工作?

时间:2014-04-08 22:49:48

标签: java methods final

我有一个非常简单的问题,只是想要了解更多有关final方法参数的信息。

final个变量只能在其生命中初始化一次。在JAVA方法中,参数被接受为按值传递,并且引用也作为值传递。

现在我的问题是:

方法怎么不知道传递的对象是final并且已经初始化了?

以下是示例代码:

public static void xyz(Abc obj) {
    System.out.println("hash code in xyz method :"+obj.hashCode());
    obj = new Abc(); // here there is no issue to initialize it again
}

public static void abc() {
    final Abc obj = new Abc();
    //obj=new Abc(); // final variable can be initialized just once

    System.out.println("hash code in abc method :"+obj.hashCode());
    xyz(obj);
}

public static void main(String[] a) {
    abc();
}

4 个答案:

答案 0 :(得分:3)

那是因为引用按值传递;你不能重置Java中的引用。如果将obj重新分配给其他内容,则只会在方法范围内重新分配,而不是在调用范围内。所以你拥有的只是最终变量引用的副本

因此"终结"没有违反原始对象。

如果你想让参数也是最终的,你可以简单地做:

public String myMethod(final Object myParameter) {
   ...
}

我认为您可能会将final变量与不变性混淆。不变性是完全不同的。这意味着一旦初始化就不能修改底层对象的状态。引用此对象的变量可能是也可能不是final;它与对象的可变性或不变性无关。实际上,final变量指向的对象可以被修改(如果它是可变的)并且使用final将无法防范。 做什么防范的是重新分配的可能性。

答案 1 :(得分:2)

绘画时间

    Object          Reference    
 [some object]  <---  1234

和你的变量

       initialized with value
obj    ---------------------->    1234

它无法再更改,因为它是final

当您将其用作参数时

xyz(obj);
...
public static void xyz(Abc someRandomNameNotToBeConfused) {

Java获取obj的值,引用1234并将其绑定到someRandomNameNotToBeConfused

现在

                                initialized with value
someRandomNameNotToBeConfused   ---------------------->    1234

someRandomNameNotToBeConfused可以更改,因为它不是final。所以如果你有第二个Abc对象

    Object          Reference    
 [some object]  <---  1234
 [other object] <---  678

您可以更改someRandomNameNotToBeConfused持有的引用

someRandomNameNotToBeConfused = new Abc(); // 678

变为

                                reassigned to
someRandomNameNotToBeConfused ------------------> 678

调用方法中的变量obj保持不变。

答案 2 :(得分:1)

obj中的abc变量与obj中的xyz参数不同。当您致电xyz时,xyz使用参考的副本(注意:这是不是对象的副本,但它&# 39;参考文献的副本)。因此,当obj = new Abc()中执行xyz时,它仅修改xyz中的副本。它对obj中的abc()没有影响,因为引用是按值传递的。

答案 3 :(得分:0)

引用是最终的,但它指向的对象不是。当引用传递到xyz时,它将被复制,因此不会修改原始引用。

最终参考文献的副本也没有理由也是最终的。 abc()中的引用是最终的,但xyz()中的引用不是。

如果您使用C++之类的语言,这可能看起来像const违规,其中const引用传递给非const的函数参数,但Java的final不起作用。

请注意,hashCode()可以被对象的类定义覆盖,因此即使创建了新对象,它也可能相等。