[英]Getter for private member object in Java
Say I have a class called Truck
and one of the private member variables is of class Wheel
. 说我有一个叫做Truck
的类,私有成员变量之一是Wheel
类。 A getter for the Wheel
variable, getWheel
, would return a reference to it, as follows: Wheel
变量getWheel
getter将返回对其的引用,如下所示:
class Truck{
private Wheel wheel;
Truck(){
wheel=new Wheel();
}
Wheel getWheel(){
return this.wheel;
}
}
class Wheel{
int color;
}
Now, whoever calls getWheel
will be able to modify the private member object at will: 现在,调用getWheel
任何人都可以随意修改私有成员对象:
class me{
public static void main(String[] args){
Truck ye=new Truck();
Wheel v=ye.getWheel();
v.color=2;
}
}
This would defeat encapsulation, wouldn't it? 这会破坏封装,不是吗?
What would be the right remedy for this? 什么是正确的补救办法?
The usual approaches are: 通常的方法是:
Wheel
) 制作防御性副本(例如,返回Wheel
的副本 ) Wheel
immutable (any time you want to change it, you create a new one instead, constructed with the new color) 使Wheel
不可变(任何时候要更改它,都可以创建一个新的,并以新的颜色构造) Wheel
, return an immutable interface on Wheel
that only exposes getters, no mutation operations 不要返回Wheel
,返回一个不可变的接口Wheel
,只有公开干将,没有变异操作 public
for the getter. 由于桑迪普说 ,使二传手比吸气更多限制,比方说,包装和私营部门的setter和public
的吸气剂。 Then classes within the package could set the color of Wheel
, but classes outside the package cannot. 然后,包装内的类可以设置Wheel
的颜色,但是包装外的类不能设置。 (I prefer #3 in this situation for the clear separation, but this works too if you're crossing a visibility boundary.) (在这种情况下,我更倾向于使用#3来实现清晰的分隔,但是如果您越过可见性边界,也可以这样做。) That third option is one of the reasons why making instance variables (fields) non- private
is often considered poor practice. 第三种选择是为什么通常将实例变量(字段)设为非private
的原因之一。
Here's #3 in more depth, just because it's more complicated than #1 and #2, not because it's necessarily better (it isn't, design choices are made in context). 这里的#3更深入,只是因为它比#1和#2更复杂,而不是因为它必须更好(不是,设计选择是在上下文中做出的)。
A read-only interface, typically public or package-private depending on how you're going to use all of this stuff: 只读接口,通常为public或package-private,具体取决于您将如何使用所有这些东西:
public interface Wheel {
int getColor();
}
The concrete class, typically package-private (could be a private static nested class within Truck
if that's the only place it's used): 具体的类,通常是package-private(如果是在Truck
上使用的唯一位置,则可以是Truck
的私有静态嵌套类):
class WheelImplementation implements Wheel {
private int color;
WheelImplementation(int color) {
this.color = color;
}
public int getColor() {
return this.color;
}
void setColor(int color) {
this.color = color;
}
}
Truck
, typically same visibility as Wheel
: Truck
,通常与Wheel
相同的能见度:
public class Truck {
private WheelImplementation wheel;
Truck(){
this.wheel = new WheelImplementation(/*...initial color...*/);
}
Wheel getWheel() {
return this.wheel;
}
}
Sure, that can be defeated through reflection, but generally you design an API for use, rather than for abuse. 当然,可以通过反射来克服它,但是通常您设计的API是使用而不是滥用。 :-) :-)
You can make a private/package setter for wheel color. 您可以为车轮颜色设置专用/打包设置器。 Also, initialize the color in the constructor which would help you do that. 另外,在构造函数中初始化颜色,这将帮助您实现这一目标。
And like other answers, returning a copy of Wheel is also a good way to do this. 与其他答案一样,返回Wheel的副本也是执行此操作的好方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.