可以修改最终对象,但不能更改引用变量

时间:2013-02-21 08:35:52

标签: java

标记为最终倾斜的参考变量重新分配给不同的对象。可以修改对象中的数据,但不能更改参考变量。

基于我的理解我在下面创建了一个代码,我试图重新分配一个新的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;  
}

我相信我误解了上述概念。

请举例说明。

感谢回复。

6 个答案:

答案 0 :(得分:8)

无法使用“=”运算符更改最终值。如果这样做,您尝试更改引用(或原始)和final状态,这是无法更改的。

可以更改现有对象的字段:

public static final User user = NewUser(145);

    public static void main(String[] args)
    {
        user.setId(155);
    }

答案 1 :(得分:5)

在您修改后的问题中,更改会使其生效,我不确定这是否是您想要的。

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

现在objChildClass是final,你可以修改它的成员,但不能改变它指向的对象。 UserId不再是最终版本,因此可以更改。

答案 2 :(得分:4)

您对这个概念的理解是正确的。等等我会尝试解释最终关键字的美感。我将它分为三部分:

  1. 如果您对任何成员使用final关键字(局部变量/实例变量/方法),则意味着您无法在整个过程中修改该特定变量的值(如果方法不能被覆盖)你的计划。
  2. 如果你将一个类声明为final,则意味着没有其他类(在相同或不同的包中)可以扩展该类(final类),换句话说,最终的类永远不能被子类化,但是, final类可以用作“超类引用”。
  3. 第三个是您所指的案例。如果任何对象引用变量被声明为final,则意味着最终引用变量在其整个生命周期中永远不会引用不同的对象,但可以修改对象内的数据(引用变量所指的对象)。
  4. 我在这里写了一篇课,希望能澄清你所有的疑惑。

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

    这是在这里实例化的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;
    }
    
    }
    

    您尝试在计算机上以不同方式运行它。

    快乐编码:)

答案 3 :(得分:2)

int是基本类型,而不是对复杂类型的引用。 http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

答案 4 :(得分:2)

UserId的类型为int,它是一种基本类型,因此应用的规则与对象不同。原始变量不是指针而是值本身。但即使您使用的是Integer(对象类型),也无法更改其值,因为基元的包装类型是不可变的。

答案 5 :(得分:2)

  

我相信我误解了上述概念。

你说得对,但你没有正确测试它。如果UserId是一个具有id(或任何名称)属性的类,那么您将能够更改它的值而不是引用。

在这里,您要创建一个基本类型变量而不是对象。尝试使用包装类Integer进行相同的测试。