7

标记为 final 的引用变量不能重新分配给不同的对象。对象中的数据可以修改,但引用变量不能更改。

根据我的理解,我在下面创建了一个代码,我试图重新分配 155 的新 UserId。随着定义的进行,我只是试图更改对象内的数据。但是参考是一样的。

public class FinalClass 
{   
    public static void main(String[] args)
    {
        ChildClass objChildClass = new ChildClass(); 
        objChildClass.UserId = 155;
    }
}

class ChildClass
{
    public static final int  UserId = 145;  
}

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

请举例说明。

谢谢您的回复。

4

6 回答 6

9

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

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

public static final User user = NewUser(145);

    public static void main(String[] args)
    {
        user.setId(155);
    }
于 2013-02-21T08:37:09.000 回答
8

你对这个概念的理解是正确的。等等,我将尝试解释 final 关键字的美妙之处。我把它分成三个部分:

  1. 如果您对任何成员(局部变量/实例变量/方法)使用 final 关键字,则意味着您无法在整个程序中修改该特定变量的值(如果方法,则不能被覆盖)。
  2. 如果您将一个类声明为最终类,则意味着没有其他类(在相同或不同的包中)可以扩展该类(最终类),换句话说,最终类永远不能被子类化,但是,最终类可以用作“超类参考”。
  3. 第三是你所指的情况。如果任何对象引用变量被声明为 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;
}

}

你尝试在你的机器上以不同的方式运行它。

快乐编码:)

于 2017-04-05T17:45:16.357 回答
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 不再是最终的,因此可以更改。

于 2013-02-21T08:43:28.193 回答
2

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

于 2013-02-21T08:37:46.980 回答
2

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

于 2013-02-21T08:38:15.877 回答
2

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

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

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

于 2013-02-21T08:39:15.623 回答