java - 从 final 字段传递可达的对象是什么意思?

标签 java immutability

This post讨论从 final 字段传递可达的不可变对象(immutable对象):

Immutability doesn't mean "does not change" in Java. It means "is transitively reachable from a final field, has not changed since the final field was set, and a reference to the object containing the final field did not escape the constructor".

对于下面的代码,

public class A() {
    private String myString;
    public A(String myString){
        this.myString = myString;
    }
    public String getMyStringAndYours(){
        return myString.concat("yours");
    }
}

A 实例是否可以从 final 字段传递到达? 我认为是因为:
1. myString.valuefinal
2. myString 可从 myString.value 访问
3. A 的实例 a 可从 a.myString

访问

附带问题:a 是不可变的吗?

最佳答案

我暂时将传递可达放在一边,集中讨论finalimmutability 之间的区别。

class MyObject {
int a;
void setA(int val){
a=val;
}
}

final MyObject obj = new MyObject(); 

现在,由于 obj referencefinal 如果您尝试这样做,您将遇到编译错误

obj = new MyObject(); // you can't re-initialize a final reference.

但是你可以做什么:

obj.setA(5); // perfectly valid.

您可以更改 obj 引用的对象的状态,但不能将 obj 重新初始化为其他对象

现在,如果 MyObject 中的所有字段都是 final 并且所有 setter 都是私有(private)的(或不存在),那么就没有办法了

obj.setA(5); 

不可变 对象是其内部状态无法更改的对象。

现在,回到传递可达。如果对象 A 由对象 B 组成,而对象 B 又包含对象 C(组合)。你的对象 A 不是真正的不可变,除非所有传递可达的对象都是不可变final,即 a.b.c here a ,b 和 ,c 应该是最终的,以防止重新分配对另一个对象的引用。此外,您应该确保在创建 a 时不共享 c(脱离 A 的范围)。如果它是共享的,那么任何其他对象都可以更改它。

编辑:

字符串是不可变的,因此,您只需要将它们设为final,以便它们的封闭类是不可变的

关于java - 从 final 字段传递可达的对象是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25397763/

相关文章:

java - 首选可变或不可变集合作为方法参数

java - 如何将 'next generation' java 数据对象样式与接口(interface)一起使用?

javascript - 浏览器 API 返回的对象是 const 吗?

java - 如何让滚动条平滑滚动?

java - 为什么 HttpClient 不发送我的 Cookie?

java - 速度空值和空字符串

java - 享元模式对象是不可变的?

java - 是否有任何模式可用于实现 holder 对象的可变和不可变版本?

java - Android Studio在fragment中添加ImageView时出错

java - 如何从 Hbase 启用 Ganglia 的新指标?