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

Java 可以修改最终对象,但不能更改引用变量,java,Java,标记为“最终铁路超高”的引用变量已重新分配给不同的对象。可以修改对象中的数据,但不能更改引用变量 根据我的理解,我在下面创建了一个代码,我试图重新分配一个新的用户ID 155。按照定义,我只是试图更改对象中的数据。但参考文献是相同的 public class FinalClass { public static void main(String[] args) { ChildClass objChildClass = new ChildClass();

标记为“最终铁路超高”的引用变量已重新分配给不同的对象。可以修改对象中的数据,但不能更改引用变量

根据我的理解,我在下面创建了一个代码,我试图重新分配一个新的用户ID 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;  
}
我相信我误解了上述概念

请举例说明


谢谢回复。

您不能使用“=”运算符更改最终值。如果这样做,您将尝试更改引用(或原语),并且
final
声明这是无法更改的

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

public static final User user = NewUser(145);

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

int是基元类型,而不是对复杂类型的引用

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

我相信我误解了上述概念

您的测试是正确的,但是您没有正确地测试它。如果UserId是一个具有
id
(或任何名称)属性的类,那么您可以更改它的值,但不能更改引用


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

在您修改的问题中,更改将使其工作,我不确定这是否是您想要的

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,您可以修改它的成员,但不能更改它指向的对象。用户ID不再是最终的,因此可以更改。

您对该概念的理解是正确的。等等,我会尝试解释最后一个关键词的美。我把它分为三个部分:

  • 如果您对任何成员(局部变量/实例变量/方法)使用final关键字,则意味着您无法在整个程序中修改该特定变量(If-method,不能过度使用)的值
  • 如果您将一个类声明为final,那么这意味着没有其他类(在相同或不同的包中)可以扩展该类(final类),换句话说,final类永远不能被子类化,但是final类可以用作“超类引用”
  • 第三是你所指的情况。如果任何对象引用变量被声明为final,则意味着final引用变量在其整个生命周期中永远不能引用其他对象,但可以修改对象(引用变量所引用的对象)中的数据
  • 我在这里写了一节课,希望能澄清你所有的疑问

    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;
    }
    
    }
    
    您尝试在您的机器上以不同的方式运行它


    快乐编码:)

    首先,您的程序中没有任何引用,那么“但是引用是相同的”是什么意思?您的代码甚至不会编译。原语不是引用
    int
    不是引用类型。@R.J这就是问题,我没有得到这个答案。即使他将
    int
    更改为
    Integer
    这是一种引用类型,它也不会起作用。@aioobe回答者说它不会起作用,因为
    Integer
    是不可变的。但是如果将
    int
    更改为自定义
    MutableInteger
    类型,则可以执行类似
    MutableInteger.set(155)
    的操作,并更改对象的封装状态。解释得很好。感谢S Kumar:)