Java 中,一个 final 的 List 变量,被往里加了元素,算不算违反了 final 这个关键词在这里暗示的约定?

2021-12-31 10:44:16 +08:00
 Newyorkcity
final 关键词在 java 中,只能保证变量的值不变,但如果变量的值是一个本身提供了修改自身的方法的对象,那调用这一方法对值(内部)做修改,final 是约束不到的。

然而这样的修改,是否是违背了 final 这个关键词放在这里时暗示的约定——该变量是不可变的?或者说,如果让一个全知全能的家伙来编写 Java ,它是否会为 final 所修饰的变量保证无论如何都无法被修改而不仅仅只是引用无法被修改的限制?(也就是说,java 之所以不能实现到这一步,是否可能是因为在编译器层面强制实现这一程度所需要的工程量太大划不来)

谢谢
4854 次点击
所在节点    问与答
55 条回复
meeop
2021-12-31 14:49:33 +08:00
你说的对,final 和浅拷贝一样,都只管变量引用本身,不管更深层次的变量持有数据,纯粹从语义上看是效果是不对的

不过,毕竟编程语言是需要和性能妥协的,深层次不可变约束会引入更多性能成本,也许未来的编程语言能支持上
otakustay
2021-12-31 15:17:26 +08:00
我还以为楼主在纠结 final 的自然语义,结果发现他被程序语义说服了……
leaves615
2021-12-31 17:04:24 +08:00
final int a = 0; //值赋值
final AtomInteger a = new AtomInteger(0); //引用对象(也就是指针)赋值
final 修饰符是用来标识变量赋值后不能进行重复赋值
final int a 只能赋值一次。
而 final AtomInteger a 也是赋值一次(指针赋值)
sdushn
2021-12-31 17:54:23 +08:00
final 是对 对象地址的限定。
final int a = 0 ,a 变为 1 是不可接受的。并非是值的变化不可接受,而是 a 对象地址不能变,如果 值 0 所在的地址可以变更为 值 1 ,那么 a 的值也可以从 0 变 1 。
kamal
2021-12-31 18:05:56 +08:00
看了大家的解释,感觉跟 ES 语法的 const 一个意思。
Greatshu
2021-12-31 18:30:36 +08:00
折腾一下 C 指针就明白了
GrayXu
2021-12-31 18:36:20 +08:00
@Newyorkcity 不是,到底是谁和你说 java 没有引用的。。。
moonmagian
2021-12-31 18:55:45 +08:00
cpp 为了区分这种区别有 logical 和 physical 的 const ,physical const 是指值本身的不变性,而 logical const 指从引用 /指针的视角看指向的对象时的不变性(尽管这个对象可能并不是 physical const )。
java 对引用类型变量的 final 声明更类似 cpp 中的 physical const (指针本身的不变性,T* const ),而不是 logical const (指针指向对象从指针视角看的不变性,const T*),只是 final 对值类型的变量有特殊的逻辑( const T )
SingeeKing
2021-12-31 19:01:21 +08:00
其实就是设计缺陷吧,例如 Rust 就增加了 mut 关键字来专门标识是否允许修改
wiix
2021-12-31 20:18:35 +08:00
Collections.unmodifiableList(list)
List.of(list.toArray(new String[]{}))
Dragonphy
2021-12-31 21:53:48 +08:00
这个我记得属于 JVM 的范畴,可以看看相关书籍技能
bsg1992
2021-12-31 22:06:56 +08:00
完全不一样的 final 修饰的是 内存引用不能改变。 你 add 没有改变内存指向。
season8
2021-12-31 22:19:32 +08:00
List 集合 -->火车见过吧,就比作火车好了
final List --> D3062 次列车就是这个编号 xxx 的车,不能用别的车
每天坐的人不一样能说 火车变了吗,火车还是那个火车。
其实就是一个概念的问题,你认为 一个 List 就应该是 List + 它的元素 ,但很明显 Java 设计的就是 List 只是容器,你说的这层 “final” 只能你自己去实现。

了解概念区别就行了,再探究下去感觉没啥意义。
Cbdy
2021-12-31 22:39:22 +08:00
totoro52
2022-01-01 14:10:23 +08:00
一个杯子 装了水,你倒了,换成了可乐,你能说这个杯子的物理性质发生了变化吗

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://ex.noerr.eu.org/t/825448

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX