为什么吸气剂和吸气剂如果返回值是可变的,则设置器?
在 C++ 中,getter &由于能够通过 const 返回值控制可变性,因此私有数据成员的 setter 非常有用。
在Java中,如果我理解正确的话(如果我错了,请纠正我),在 getter 上指定 final
是行不通的。一旦调用者通过 getter 接收到数据成员引用,它就可以修改它,尽管它是私有的......
如果是这样的话(如果我在这里有一个严重的误解,请纠正我),为什么不声明数据成员 公开
并简化事情?
In C++ a getter & setter for a private data member is very useful due to the ability to control mutability via a const
return value.
In Java, if I understand correctly (please correct me if I am mistaken), specifying final
on a getter doesn't work that way. Once the caller received the data member reference through the getter, it can modify it, despite it being private...
If that's the case (and please correct me if I have a gross misconception here), why not declare the data member public
and simplify things?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
在 java 中使
不可变
返回值是一个或者返回已经不可变
对象类型的问题(例如String)或返回非不可变对象的副本。示例 1 - 已经不可变的对象
示例 2 - 已经不可变的对象的集合
示例 3 - 非不可变的对象
示例 4 > - 非不可变对象的集合
示例 3 和 4 是为了方便起见,因为复杂类型实现了
Cloneable
接口。此外,为了避免子类覆盖不可变方法,您可以将它们声明为
final
。附带说明一下,builder
模式通常很有用用于构造不可变对象。Making
immutable
return values in java is a matter of either returning alreadyimmutable
objects types (such as String) or returning a copy for non-immutable objects.Sample 1 - Already immutable object
Sample 2 - Collection of already immutable objects
Sample 3 - Non-immutable object
Sample 4 - Collection of non-immutable objects
Sample 3 and 4 are for conveniance based on that the complex type implements the
Cloneable
interface.Furthermore, to avoid subclasses overriding your immutable methods you can declare them
final
. As a side note, thebuilder
pattern is typically useful for constructing immutable objects.如果您希望您的类是不可变的(即只有
final
字段和 getter),您必须确保返回的值也是不可变的。返回字符串和内置基元时,您可以免费获得此功能,但是对于其他数据类型,需要一些额外的步骤:Date
和Calendar
克隆
它们。这也适用于集合中的对象。请注意,如果您防御性地复制集合,则客户端可以查看或修改副本,但这不会影响原始集合:
另一方面,如果您包装原始集合,则客户端能够看到引入的所有更改创建包装器后到集合,但尝试更改包装器的内容将导致运行时异常:
底线是:
Foo
也必须是不可变的,否则集合是不可变的,但客户端代码仍然可以修改集合的成员。因此同样的规则也适用于Foo
。因为:
If you want your class to be immutable (i.e. having only
final
fields and getters) you must be sure that the values you return are immutable as well. You get this for free when returning Strings and built-in primitives, however some extra steps are necessary for other data types:Date
andCalendar
clone
them. This also applies to objects in collections.Note that if you defensively copy a collection, the client can view or modify the copy, but this does not affect the original collection:
On the other hand if you wrap the original collection, the client is able to see all the changes that were introduced to the collection after the wrapper was created, but trying to change the contents of the wrapper will result in runtime exception:
The bottom line is:
Foo
has to be immutable as well, otherwise the collection is immutable, but the client code can still modify members of the collection. So the same rules apply toFoo
.Because:
如果您想返回可变标准容器(例如列表)的不可变视图,那么您应该查看 Collections 库:
http://download.oracle.com/javase/1.4.2/docs/api/java/util/Collections.html
它提供了一些有用的包装器,例如 unmodifyingMap 和 unmodifyingList。这样您就不必制作浪费的副本。当然,如果列表的元素是可变的,那么这不会有太大帮助——Java 中没有简单的方法来获得“深度”不变性。当然,在 C++ 中也是如此——例如,如果您有一个指向 Foo 对象的指针的 const 向量,那么 Foo 对象本身仍然可以被修改(因为 const 不会跨指针传播)。
If you want to return an immutable view of a mutable standard container (eg list), then you should take a look at the Collections library:
http://download.oracle.com/javase/1.4.2/docs/api/java/util/Collections.html
It provides some useful wrappers such as unmodifiableMap and unmodifiableList. That way you don't have to make a wasteful copy. Of course, if the elements of the list are mutable, then this won't help as much -- there's no easy way in Java to get "deep" immutability. Of course, the same is true in C++ -- e.g., if you have a const vector of pointers to Foo objects, then the Foo objects themselves can still be modified (because const doesn't propagate across pointers).
首先,JavaBeans 规范。要求您提供 getter(以及可变属性的 setter)。
其次,getter 可能使您能够添加一些逻辑,例如,一个 getter 可能实际上决定返回什么(例如,如果属性为 null,则返回一些不同的东西)。如果一开始就没有吸气剂,那么以后添加这样的逻辑就会遇到更多麻烦。使用吸气剂,您只需更改方法而无需接触调用者。
First of all, the JavaBeans spec. requires you to provide getters (and setters for mutable properties).
Second, getters might enable you to add some logic, e.g. one getter might actually decide what to return (e.g. if the property is null return something differenc). If you didn't have getters in the first place you'd have more trouble to add such logic later on. With getters you'd just change the method without touching the callers.
因为信息隐藏使得管理和维护复杂的代码库变得更加容易。如果数据成员是私有的,您可以在一个类中更改表示和行为,而不是在整个大型代码库中更改。
为了澄清,调用者不能修改从 getter 返回的数据成员。它也许能够修改数据成员指向的对象。
如果这是一个问题,并且您通过 getter 提供访问权限,则可以返回一个不可变的实例或防御性副本。
setter 对于控制对引用对象的修改也很有价值。您可以在二传手中制作防守副本。
Because information hiding makes it easier to manage and maintain a complex codebase. If the data members are private, you can change representation and behavior in one class, rather than throughout a large codebase.
To clarify, a caller cannot modify a data member returned from a getter. It might be able to modify an object to which the data member points.
If this is a problem, and you're providing access through a getter, you can return an immutable instance, or a defensive copy.
The setter is also valuable for controlling modification to a referenced object. You can make a defensive copy in the setter.