Java中私有成员对象的Getter

时间:2017-03-31 07:14:56

标签: java oop

假设我有一个名为Truck的类,其中一个私有成员变量属于类WheelWheel变量getWheel的getter将返回对它的引用,如下所示:

class Truck{
    private Wheel wheel;

    Truck(){
        wheel=new Wheel();

    }

    Wheel getWheel(){
        return this.wheel;
    }
}

class Wheel{
    int color;
}

现在,无论谁调用getWheel都可以随意修改私有成员对象:

class me{
    public static void main(String[] args){
        Truck ye=new Truck();
        Wheel v=ye.getWheel();

        v.color=2;
    }
}

这会打败封装,不是吗?

对此有什么补救措施?

2 个答案:

答案 0 :(得分:8)

通常的做法是:

  • 制作防御性副本(例如,返回Wheel副本
  • Wheel不可变(任何时候你想要改变它,你创建一个新的,用新颜色构建)
  • 不要返回Wheel,在Wheel上返回一个只会暴露getter,不会发生变异操作的不可变接口
  • As Sandeep said,使 setter getter 更受限制,例如,set-private为setter,public为getter。然后包中的类可以设置Wheel的颜色,但包外的类不能。 (在这种情况下,我更喜欢#3,以便明确分离,但这也很有效如果你越过可见性边界。)

第三个选项是将实例变量(字段)设为非private通常被视为不良实践的原因之一。

这里的#3更深入,仅仅因为它比#1和#2更复杂,不是因为它必然更好(它不是,设计选择是在上下文中制作。)

一个只读界面,通常是公共的或包私有的,具体取决于您将如何使用所有这些内容:

public interface Wheel {
    int getColor();
}

具体类,通常是package-private(如果它是唯一使用过的地方,可以是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,通常与Wheel的可见度相同:

public class Truck {
    private WheelImplementation wheel;

    Truck(){
        this.wheel = new WheelImplementation(/*...initial color...*/);
    }

    Wheel getWheel() {
        return this.wheel;
    }
}

当然,这可以通过反思来消除,但通常你设计一个API供使用,而不是滥用。 : - )

答案 1 :(得分:2)

您可以为车轮颜色制作私人/包裹设定器。 此外,初始化构造函数中的颜色,这将有助于您这样做。

和其他答案一样,返回Wheel的副本也是一种很好的方法。