简体   繁体   English

Java中私有成员对象的Getter

[英]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: 通常的方法是:

  • Make a defensive copy (eg, return a copy of Wheel ) 制作防御性副本(例如,返回Wheel副本
  • Make Wheel immutable (any time you want to change it, you create a new one instead, constructed with the new color) 使Wheel不可变(任何时候要更改它,都可以创建一个新的,并以新的颜色构造)
  • Don't return Wheel , return an immutable interface on Wheel that only exposes getters, no mutation operations 不要返回Wheel ,返回一个不可变的接口Wheel ,只有公开干将,没有变异操作
  • As Sandeep said , make the setter more restricted than the getter , say, package-private for the setter and 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM