仅通过java中的方法强制私有成员从同一个类访问

时间:2011-09-14 08:43:30

标签: java reflection junit

我希望强制类的未来用户也可以通过访问器方法(甚至通过junit或类似的东西)从该类中编写的未来代码访问私有成员。

有没有办法在java中做到这一点?如果有可能,有人可以展示一个例子吗?

7 个答案:

答案 0 :(得分:3)

您无法强制执行此操作,但您可以在javadoc中创建方法并记录该强制执行。

private int myMember;

/**
* ATTENTION: use this method instead of setting the member directly.
*/
public void setMyMember(int value) {
  this.myMember = value;
}

此外,还有一种可行的替代解决方案。使用ThreadLocal,如下所示:

private final ThreadLocal<String> member = new ThreadLocal<String>();

public void setMember(final String value) {
  member.set(value);
}

会员字段是最终的,无法更改。因此,客户将被迫直接调用setter。

答案 1 :(得分:2)

如果要防止反射,可以使用SecurityManager。如果这不是一个选项,你可以通过Thread.currentThread()获取调用堆栈.getStackTrace()并检查调用者是否来自你的类。

这有两个问题:表现不会很好。您可以在外部执行的方法中执行任何操作,因此最简单的方法是在不进行检查的情况下复制其内容。 ;)

我建议您记录不允许以这种方式访问​​的原因。

答案 2 :(得分:2)

利用继承来隐藏字段:

  • 使用您需要的所有字段和getter / setter来上课。 (你可以把它抽象化)
  • 做一个继承自预览的子类,由于该字段不可访问,因此强制使用getter / setter对。

答案 3 :(得分:2)

只要该字段是该类的一部分,任何人都可以直接访问它。当我们试图强迫所有(共同)作者通过getter / setter时,这可能是一个问题,因为这些方法会进行一些转换,检查或记账。就像递增内部计数器一样。

一般的解决方案,我想到:通过使用注释可以实现。您必须创建一个注释(和注释处理器代码),以确保如果该字段在其getter / setter方法之外使用,那么它是编译时错误:

@GetterSetterAccessOnly
private int value;

答案 4 :(得分:0)

当你在谈论在同一个班级中访问时,他们可以直接访问私有成员,也可以通过访问者方法访问该成员。 所以基本上你不能阻止他们直接在同一个班级使用这个成员。

答案 5 :(得分:0)

恐怕没有标准的方法可以做到这一点。如果用户有权访问类实例,虽然私有成员被声明为私有,但是可以在运行时更改权限并进行访问。

您需要一个强制执行权限的类加载器。您可以创建OSGi Bundle并对通过接口作为服务导出的对象实例实施控制策略。但是,这会将您绑定到OSGi容器以运行您的应用程序。

答案 6 :(得分:0)

好吧,如果他们可以访问您的代码,他们可以做任何他们想做的事情。在最糟糕的情况下,他们会删除你的吸气剂和制定者而只是放入公共场地;)

但是当然你可以激励他们不要直接使用相应的设计访问变量:

  • 您应该检查其他人是否应该实现子类而不是更改类本身。那么私人领域当然只能通过制定者和吸气剂进行访问。
  • 您可以将数据移动到其他类,并使用getter和setter访问其他类中的数据。这样做只是为了不直接在你的班级中使用数据可能有点违反直觉,但由于你可能有充分的理由不应该访问那些数据,这表明了不同的责任。因此,重构以满足SRP是一个好主意。