这无法实现,您无法实例化已经实例化的最终对象:
private void myMethod(){
final Object object = null;
object = new Object();
}
Eclipse会给出一条错误消息:
无法分配最终的局部变量对象。它必须为空白且不使用复合赋值
但是,如果将此对象传递给另一个方法:
private void _myMethod(Object object){
object = new Object();
}
这可以实现!
最终形式:
private void myMethod(){
final Object object = null;
_myMethod(object);
}
private void _myMethod(Object object){
object = new Object();
}
有人能解释一下吗? Java的运作方式令人困惑。
答案 0 :(得分:4)
首先,变量名称很难解释,所以:
private void myMethod(){
final Object finalObject = null;
_myMethod(finalObject);
}
private void _myMethod(Object methodObject){
methodObject = new Object();
}
Java通过引用值传递对象。将参数传递给方法意味着methodObject
保存了对finalObject
的引用副本(但不包含对象的副本)。现在,方法的主体不会更改或重新分配finalObject
对象 - 它只是通过更改传递给方法的引用值来重新分配methodObject
。
请参阅this answer - 我想它会更清楚。
答案 1 :(得分:0)
你必须在这里理解局部变量的概念。
见下图
所有局部变量(基元或对象)都将驻留在其方法堆栈中。
如果它是一个对象,则只引用保留在堆栈中,并且对象驻留在堆中。
并且每个局部变量都放在方法堆栈中。
所以此处2 local variables
会在stack
中为每个方法添加一个。
其中一个是final
而另一个不是。
所以你可以reassign
第二个而不是第一个。
在你的情况下,
final Object object = null
存储在myMethod
堆栈中。并在此声明为最终版,
所以在这种方法中你不能再分配它。
然而在里面
private void _myMethod(Object object){
object = new Object(); //Error here
}
Object object
声明生成相同的变量以在_myMethod
堆栈位置内获取空间。
所以这里not final
因此它可以是reassigned
。
如果你在这个方法中使用final
,那么我的图像中的第二张图片将在其方法堆栈中包含最终Object
变量,然后它将不允许第二次分配。
答案 2 :(得分:0)
在java变量中passed by value。对于Objects,它是传递的引用的副本。
private void myMethod(){
final Object object = null;
_myMethod(object);
}
private void _myMethod(Object newObject){
newObject= new Object();
}
因此newObject
是一个新的引用,如果类型为Object,指向object
所指向的同一个Object。请注意,对象引用是最终的,而不是副本,即newObject 。所以你所做的是第二部分完全有效。
public class Test{
final Object object = null;
private void myMethod(){
_myMethod(object);
}
private void _myMethod(Object newObject){
object = new Object(); //Error here
}
}
以上将失败,因为对象引用是最终的。