在类上构建一个只读包装器

时间:2011-12-16 12:54:11

标签: java interface builder

我有一个类如下:

 class A{
  // it has some getters and setters
 }

还有另一个名为builder类的类,它构建了A类

class BuilderA{
   // builds A and returns an instance.
}

现在我想准备一个readOnly类A,它确保Class newA只有ClassA的getter而不是setter。

我这样做是为了确保如果我通过这个newA我很安全,没有人可以使用getter并对newA进行任何更改,如果我直接使用A类就会发生这种情况。

有谁能告诉我怎样才能实现这个目标..?

4 个答案:

答案 0 :(得分:1)

以下是一个例子:

public class Person {
    String name;

    public Person(String name) {
        this.name = name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

public class ImmutablePerson extends Person {

    public ImmutablePerson(String name) {
        super(name);
    }

    @Override
    public void setName(String name) {
        throw new UnsupportedOperationException();
    }
}

public class PersonBuilder {
    public static Person createMutablePerson(String name) {
        return new Person(name);
    }

    public static Person createImmutablePerson(String name) {
        return new ImmutablePerson(name);
    }
}

虽然这有效,但我认为这不是用Java设计类的好方法。

引用Joshua Bloch的“Effective Java”,类应该是不可变的,除非你有充分的理由说明它们应该是可变的。

答案 1 :(得分:0)

如果你想要一个通用的问题解决方案,你必须将getter和setter提取到一个接口中,然后用Proxy拦截所有以set开头的方法或者给它们注释(并在你的注释中处理注释)处理程序)然后要么什么也不做或者最好抛出UnsupportedOperationException。

如果您只需要1或2个类,并且通常会带来更大的开销,那就太过分了。

答案 2 :(得分:0)

您可以扩展A类并实现抛出UnsupportedOperationException的setter,或者在调用时不执行任何操作。您无法关闭对A类公共setter方法的访问,仍然是A类的实例(通过子类化)。

答案 3 :(得分:0)

您可以轻松地使用Proxyjava.lang.reflect.Proxy),然后只需查看调用的方法名称(检查它是否以set开头)。开销应该相对最小,并且无需为每个额外的类编写代码。您可以使用带有进一步编码的注释来指定允许/拒绝的setter。

public static boolean isSetter(Method method){
    if(!method.getName().startsWith("set"))    return false;
    if(method.getParameterTypes().length != 1) return false;  
    return true;
}