可能重复: 为什么string不能在Java和.NET中变化? 为什么.NETstring是不可变的? 有几种语言select了这种语言,比如C#,Java和Python。 如果为了节省内存或提高像比较这样的操作的效率,它对连接和其他修改操作有什么影响?
从最近的SO问题(请参阅在Python中创build一个由列表索引的字典 ),我意识到我可能对python中的可哈希和不可变对象的含义有错误的概念。 可行性在实践中意味着什么? 可哈希和不可变的关系是什么? 有可变的对象是可哈希或不可变的不可哈代对象?
从Java 1.6 Collection Framework文档 : 不支持任何修改操作(如add , remove和clear )的集合被称为不可修改 。 […]另外保证集合对象永远不可见的集合被称为不可变的集合。 第二个标准混淆了我一点。 鉴于第一个集合是不可修改的,并且假设原始集合参考已被废弃,第二行中提到的变化是什么? 它是指在集合中所包含的元素的变化,即元素的状态? 第二个问题: 对于一个集合是不可改变的,一个人怎么去提供额外的保证人? 如果集合中元素的状态由线程更新,那么为了不可变性就足够了:状态中的那些更新在持有不可变集合的线程中不可见? 编辑:(突出第二个问题的重点): 对于一个集合是不可改变的,一个人怎么去提供额外的保证人?
如何在Java中创build不可变的对象? 哪些对象应该被称为不可变的? 如果我有所有静态成员的类是不可改变的?
可能重复: 为什么可变的结构是邪恶的? 我在很多地方读过,包括在这里最好把结构做成不变的。 这背后的原因是什么? 我看到很多微软创build的结构都是可变的,就像xna中的结构一样。 在BCL中可能还有更多。 不遵循这个准则有什么优点和缺点?
如果一个元组是不可变的,为什么它可以包含可变项目? 看起来是一个矛盾,当一个可变项如列表被修改时,它所属的元组保持不变。
冻结集是一个冻结集。 一个冻结的列表可能是一个元组。 冻结字典是什么? 一个不可改变的,可拆分的字典。 我想这可能是像collections.namedtuple ,但更像是一个冻结键字典(半冻结字典)。 不是吗? “frozendict”应该是一个冷冻字典,它应该有keys , values , get等等,并支持,等等。
虽然我从来没有需要这样做,但让我感到惊讶的是,在Python中创build一个不可变的对象可能有点棘手。 你不能只是覆盖__setattr__ ,因为你甚至不能在__init__设置属性。 inheritance一个元组是一个有效的技巧: class Immutable(tuple): def __new__(cls, a, b): return tuple.__new__(cls, (a, b)) @property def a(self): return self[0] @property def b(self): return self[1] def __str__(self): return "<Immutable {0}, {1}>".format(self.a, self.b) def __setattr__(self, *ignored): raise NotImplementedError def __delattr__(self, *ignored): raise NotImplementedError 但是你可以通过self[0]和self[1]来访问a和bvariables,这很烦人。 纯Python中可能吗? 如果没有,我将如何做一个C扩展? (仅在Python 3中工作的答案是可以接受的)。 更新: 因此,子类化元组是在纯Python中执行的方式,除了[0] , [1]等访问数据的额外可能性,这种方法运行良好。因此,要完成这个问题,所有缺less的就是如何“正确“的C语言,我认为这很简单,只是没有实现任何geititem或setattribute等等。但是我自己却没有这么做,因此我提供了一个奖励,因为我很懒。 🙂
怎样才能使Java类不可变,什么是不变性的需要,使用它有什么好处?
我们都知道String在Java中是不可变的,但请检查以下代码: String s1 = "Hello World"; String s2 = "Hello World"; String s3 = s1.substring(6); System.out.println(s1); // Hello World System.out.println(s2); // Hello World System.out.println(s3); // World Field field = String.class.getDeclaredField("value"); field.setAccessible(true); char[] value = (char[])field.get(s1); value[6] = 'J'; value[7] = 'a'; value[8] = 'v'; value[9] = 'a'; value[10] = '!'; System.out.println(s1); // Hello Java! System.out.println(s2); […]