Java中的最终变量操作

Dus*_*usk 45 java variables final

任何人都可以告诉我在Java的上下文中以下行的含义:

除非它是不可变的,否则仍然可以操纵最终变量

据我所知,通过声明的任何变量,最后,你不能再改变它,那么他们的意思字不变在上述行?

Mic*_*rdt 99

这意味着如果你的最终变量是一个引用类型(即不是像int这样的原语),那么它只是一个无法更改的引用.它不能被引用到不同的对象,但是如果类允许的话,它所引用的对象的字段仍然可以被改变.例如:

final StringBuffer s = new StringBuffer();
Run Code Online (Sandbox Code Playgroud)

StringBuffer的内容仍然可以任意改变:

s.append("something");
Run Code Online (Sandbox Code Playgroud)

但你不能说:

s = null;
Run Code Online (Sandbox Code Playgroud)

要么

s = anotherBuffer;
Run Code Online (Sandbox Code Playgroud)

另一方面:

final String s = "";
Run Code Online (Sandbox Code Playgroud)

字符串是不可变的 - 根本没有任何方法可以让你更改字符串(除非你使用反射 - 然后去地狱).

  • +1*除非你使用反射 - 然后去地狱* - 只是喜欢来自糟糕经历的好幽默:))) (18认同)

Sav*_*sis 17

如果您对Java对象有最终引用,则仍可以对其进行操作,但不能更改其引用.例如,这段代码是完全合法的:

import javax.swing.JLabel;

class Test1 {
    private final static JLabel l = new JLabel("Old text");
    public static void main(String[] args) {
        System.err.println(l.getText());
        l.setText("New Text");
        System.err.println(l.getText());
    }
}
Run Code Online (Sandbox Code Playgroud)

但你不能说:

l = new JLabel("Newest Text");
Run Code Online (Sandbox Code Playgroud)

在第一次分配给l之后.请注意,您可以这样做:

import javax.swing.JLabel;

class Test1 {
    public static void main(String[] args) {
        final JLabel l;
        String s = getArbitaryString(); // Assume this method returns a string
        l = new JLabel(s);
        System.err.println(l.getText());
    }
}
Run Code Online (Sandbox Code Playgroud)

这可以完成,因为当声明l时,它不会被赋值给任何甚至不为null的东西.所以你被允许只为它分配一次.

原语也是如此.您可以像这样为其分配值:

class Test1 {
    public static void main(String[] args) {
        final int i;
        i = 2;
    }
}
Run Code Online (Sandbox Code Playgroud)

但是现在你无法进一步操纵它,因为你可以对原始类型做的唯一事情是为它们赋值.