如何确保返回的对象不会在Java中修改

时间:2015-04-14 08:18:39

标签: java

在Java中,您无法像在C ++中那样返回对象的const引用。如何返回一个对象的引用,该对象可以在类中修改但不能从外部修改?

考虑这个例子:

我有一个带有Slave类对象的A类。该对象将被返回并在A类之外使用。这是一个代码,我希望这些注释有助于理解这个问题。

public class TestReference
{
    public static void main(String[] args) {
        TestReference tr = new TestReference();
        TestReference.A a = tr.new A();

        Slave slave = a.getConstSlave();
        slave.printName();

        a.setSlaveName("New Name");
        slave.printName(); // also changes, this is a reference to the object inside class A

        slave.setName("Fake name"); //this shouldn't be able to happen, we are making modifications outside class A
        slave.printName();
    }

    private class A {
        private Slave slave;
        public A() {
            this.slave = new Slave("A");
        }
        public Slave getConstSlave() {
             // How to make sure this slave will not be modified outside
             // and will keep consistency with this object modifications
             // inside the class A
            return slave;
        }
        public void setSlaveName(String name) {
            slave.setName(name);
        }
    }

    private class Slave {
        private String name;
        public Slave(String name) {
            this.name = name;
        }
        public void printName() {
            System.out.println(name);
        }
        public void setName(String name) {
            this.name = name;
        }
    }
}

3 个答案:

答案 0 :(得分:1)

有几种选择可以与他们的职业选手一起获得。 &安培;缺点:

  1. 删除所有set方法。例如,删除setName方法,因此只能从const'中设置这些字段。或者如果你有的话,可以使用你的建造者课程。
  2. Package private - 意味着您可以从包

    中访问这些方法

    3.设置方法保护

  3. 您可以阅读有关控制对成员here

    成员的访问权限的信息

答案 1 :(得分:1)

IMO没有办法在java中这样做,就像你在C ++中那样。

你可以做的是创建一个接口(例如ReadOnlySlave)并返回而不是Slave:

public interface ReadOnlySlave {
    public void printname();
}

public class Slave : ReadOnlySlave {
   public void printname() { ... }

   public void setName() { .... }
}

public ReadOnlySlave getConstSlave() {
   return slave;
}

然后你就可以修改你班级里面的奴隶,并且变化随处可见,但在外面他们无法改变任何东西。

答案 2 :(得分:0)

没有关键字可以确保在类Slave之外无法修改返回的A对象。

但是,如果您不希望在类Slave之外公开A的修饰符,则不要定义返回整个Slave对象的方法。 而是仅公开您希望在Slave A中访问的方法。例如:

  private class A {
        private Slave slave;
        public A() {
            this.slave = new Slave("A");
        }
        public Slave getSlaveName() {
            return slave.getName();
        }

        public void setSlaveName(String name) {
            slave.setName(name);
        }

        // And any other getter/setter you would like to expose 
        // but do not return the entire Slave object
    }

换句话说,如果ASlave实例的所有者,那么让A“决定”通过定义正确的Slave实例成员将会公开的内容此Slave实例的委派方法