nst*_*olt 20 java final immutability
您能否澄清一下,为什么 在课堂上我们将最终关键字作为不可变关键字时需要它.我的意思是,如果我们将所有属性声明为private和final,那么它也是一个不可变类,不是吗?
对不起,如果问题看起来很容易,但我真的很困惑.帮帮我.
Editted:我知道一个声明final的类不能被子类化.但是如果每个属性都是私有的,那么最终会有什么区别呢?
Jon*_*eet 24
正如堆栈器所说,final确保该类不是子类.这一点非常重要,因此任何依赖其不变性的代码都可以安全地完成.
例如,不可变类型(其中每个字段也是不可变类型)可以在线程之间自由使用,而不必担心数据争用等.现在考虑:
public class Person {
private final String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
Run Code Online (Sandbox Code Playgroud)
这看起来像你可以分享Person自由地在线程之间没有任何问题的情况.但是,当您共享的对象实际上是一个可变的子类时:
public class Employee extends Person {
private String company;
public Employee(String name, String company) {
super(name);
this.company = company;
}
public void setCompany(String company) {
this.company = company;
}
public String getCompany() {
return company;
}
}
Run Code Online (Sandbox Code Playgroud)
现在,在线程之间共享Employee 是不安全的,因为它们不是不可变的.但是,进行共享的代码可能只知道它们的实例Person......导致它们陷入虚假的安全感.
缓存也是如此 - 缓存和重用不可变类型应该是安全的,对吧?那么,它是安全的缓存实例那些真正不可变型的-但如果你正在处理一个类型本身不允许突变,但不会允许子类,它是突然不是安全了.
想一想java.lang.Object.它没有任何可变字段,但将每个Object引用视为对不可变类型的引用显然是一个坏主意.基本上,这取决于您是否将不可变性视为类型或对象的属性.一个真正不可变的类型声明"任何时候你看到这种类型的引用,你可以将它视为不可变的" - 而允许任意子类化的类型不能提出这种说法.
顺便说一下,有一个中途的房子:如果你可以将子类限制为只有"受信任"的地方,你可以确保一切都是不可变的,但仍然允许子类化.Java中的访问使得这很棘手,但是在C#中你可以拥有一个只允许在同一个程序集中进行子类化的公共类 - 提供一个在不变性方面很好而且强大的公共API,同时仍然允许多态的好处.