java 可以修改最终对象但不能更改引用变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14997746/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Final object can be modified but reference variable cannot be changed
提问by Java Beginner
A reference variable marked final cant reassigned to different object.The data with in object can be modified but the reference variable cannot be changed.
标记为 final 的引用变量不能重新分配给不同的对象。对象中的数据可以修改,但引用变量不能更改。
Based on my Understanding I have a created a code below where I am trying to reassign a new UserId of 155.As the Definition goes I am only trying to change data within the object. But the reference is same.
根据我的理解,我在下面创建了一个代码,我试图重新分配一个新的 UserId 155。根据定义,我只是试图更改对象内的数据。但是参考是一样的。
public class FinalClass
{
public static void main(String[] args)
{
ChildClass objChildClass = new ChildClass();
objChildClass.UserId = 155;
}
}
class ChildClass
{
public static final int UserId = 145;
}
I believe I misunderstood the above concept.
我相信我误解了上述概念。
Kindly explain the same with example.
请举例说明。
Thanks for Reply.
谢谢你的回复。
回答by BobTheBuilder
You can'tchange final value using "=" operator. If you do it, you try to change the reference (or primitive) and final
states that this cannot be changed.
您不能使用“=”运算符更改最终值。如果您这样做,您会尝试更改引用(或原语)并final
声明无法更改。
You canchange existing object's fields:
您可以更改现有对象的字段:
public static final User user = NewUser(145);
public static void main(String[] args)
{
user.setId(155);
}
回答by Karthik T
In your modified question, a change would get it to work, I am not sure if this is what you want.
在您修改后的问题中,更改将使其起作用,我不确定这是否是您想要的。
public class FinalClass
{
public static void main(String[] args)
{
final ChildClass objChildClass = new ChildClass();
^^^^^
objChildClass.UserId = 155;
//objChildClass = new ChildClass();
}
}
class ChildClass
{
public static int UserId = 145;
^^^
}
Now objChildClass is final, you can modify its members, but not change the object it points to. UserId is no longer final so it can be changed.
现在 objChildClass 是最终的,你可以修改它的成员,但不能改变它指向的对象。UserId 不再是最终的,因此可以更改。
回答by Shubham Arya
Your understanding of the concept was right. Wait I will try to explain the beauty of final keyword. i have divided it in three parts :
你对这个概念的理解是对的。等等,我将尝试解释 final 关键字的美妙之处。我把它分成三个部分:
- If you are using final keyword for any member(local variable/instance variable/method) it means there is no way that you can modify the value of that particular variable(if method, that can not be over-ridden) throughout your program.
- If you are declaring a class as final, then, it means that no other class(in same or different package) can extend that class(final class), in other words the final class can never be subclassed, but, the final class can be used as the "Superclass reference".
- Third is the case which you are referring to. If any object reference variable is declared as final, then it means that the final reference variable can never ever in its entire life refer to a different object but the data within the object(the object your reference variable is referring to) can be modified.
- 如果您对任何成员(局部变量/实例变量/方法)使用 final 关键字,则意味着您无法在整个程序中修改该特定变量的值(如果是方法,则不能被覆盖)。
- 如果您将一个类声明为 final,则意味着没有其他类(在相同或不同的包中)可以扩展该类(final 类),换句话说,final 类永远不能被子类化,但是,final 类可以用作“超类参考”。
- 第三个是你所指的情况。如果将任何对象引用变量声明为 final,则意味着最终引用变量在其整个生命周期中永远不会引用不同的对象,但可以修改对象(您的引用变量所引用的对象)中的数据。
I have written a class here hope that clarifies all the doubts you have.
我在这里写了一个类希望能澄清你所有的疑惑。
public class FinalSampleTestDrive {
public static void main(String[] args) {
final FinalSample obj = new FinalSample();
FinalSample obj2 = new FinalSample();
FinalSample obj3 = new FinalSample();
obj2.setName("arya");
System.out.println(obj2.getName());
obj3 = obj2; //allowed
System.out.println(obj3.getName());
//obj = obj2 //not allowed as obj is final and can not be modified
obj.setName("shubham");
System.out.println(obj.getName());
//but the value of the instance variables, the obj is referring to
//can change
obj.setName("shivam");
System.out.println(obj.getName());
}
}
and this is the FinalSample class which is getting instantiated here :
这是在这里被实例化的 FinalSample 类:
public class FinalSample {
private String name;
private String age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
You try to run it in different ways on your machine.
您尝试在您的机器上以不同的方式运行它。
Happy Coding :)
快乐编码:)
回答by ollins
int is a primitive type and not a reference to a complex type. http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
int 是一种原始类型,而不是对复杂类型的引用。http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
回答by koljaTM
UserId is of type int, which is a primitive type, therefore different rules apply than for Objects. a primitive variable is no pointer but the value itself. But even if you were using an Integer (Object type), you wouldn't be able to change its value, since the wrapper types for primitives are immutable.
UserId 是 int 类型,它是一种原始类型,因此适用的规则与 Objects 不同。原始变量不是指针而是值本身。但即使您使用的是 Integer(对象类型),您也无法更改其值,因为原语的包装类型是不可变的。
回答by mtk
I believe I misunderstood the above concept.
我相信我误解了上述概念。
You got it correct, but you are not testing it correctly. If the UserId would have been a class with a id
(or any name) property, then you would be able to change the values of it but not the reference.
你猜对了,但你没有正确测试它。如果 UserId 是一个具有id
(或任何名称)属性的类,那么您将能够更改它的值,但不能更改引用。
Here you are creating a primitive type variable and not a object. Try using the wrapper class Integer for the same test.
在这里,您创建的是原始类型变量而不是对象。尝试使用包装类 Integer 进行相同的测试。