我有一个非常简单的问题,只是想要了解更多有关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();
}
答案 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()
可以被对象的类定义覆盖,因此即使创建了新对象,它也可能相等。