在Java中,我们使用带有变量的final关键字来指定其不被更改的值。
但我看到你可以改变类的构造函数/方法的值。同样,如果变量是静态的,那么这是一个编译错误。
代码如下:
import java.util.ArrayList;
import java.util.List;
class Test {
private final List foo;
public Test()
{
foo = new ArrayList();
foo.add("foo"); // Modification-1
}
public static void main(String[] args)
{
Test t = new Test();
t.foo.add("bar"); // Modification-2
System.out.println("print - " + t.foo);
}
}
以上代码工作正常,没有错误。
现在将变量更改为静态:
private static final List foo;
现在它是一个编译错误。期末考试是怎么进行的呢?
这是一个非常好的面试问题。有时他们甚至会问你final对象和immutable对象的区别是什么。
1)当有人提到一个最终对象时,这意味着引用不能改变,但它的状态(实例变量)可以改变。
2)不可变对象的状态不能改变,但其引用可以改变。
例:
String x = new String("abc");
x = "BCG";
可以修改Ref变量x指向另一个字符串,但是不能修改abc的值。
3)实例变量(非静态字段)在调用构造函数时初始化。所以你可以在构造函数中初始化变量的值。
4)“但是我看到你可以改变类的构造函数/方法的值”。—您不能在方法中更改它。
5)静态变量在类加载过程中初始化。所以你不能在构造函数内部初始化,它甚至必须在构造函数之前完成。因此,需要在声明过程中为静态变量赋值。
以下是使用final的不同上下文。
最终变量一个最终变量只能赋值一次。如果变量是引用,这意味着不能将该变量重新绑定到引用另一个对象。
class Main {
public static void main(String args[]){
final int i = 20;
i = 30; //Compiler Error:cannot assign a value to final variable i twice
}
}
Final变量可以稍后赋值(声明时不强制赋值),但只能赋一次。
Final类不能扩展(继承)
final class Base { }
class Derived extends Base { } //Compiler Error:cannot inherit from final Base
public class Main {
public static void main(String args[]) {
}
}
Final方法不能被子类覆盖。
//Error in following program as we are trying to override a final method.
class Base {
public final void show() {
System.out.println("Base::show() called");
}
}
class Derived extends Base {
public void show() { //Compiler Error: show() in Derived cannot override
System.out.println("Derived::show() called");
}
}
public class Main {
public static void main(String[] args) {
Base b = new Derived();;
b.show();
}
}