Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/345.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在java中,强制只能通过方法从同一类访问私有成员_Java_Reflection_Junit - Fatal编程技术网

在java中,强制只能通过方法从同一类访问私有成员

在java中,强制只能通过方法从同一类访问私有成员,java,reflection,junit,Java,Reflection,Junit,我想强制类的未来用户也只能通过访问器方法(甚至通过junit或类似的方法)从该类中编写的未来代码访问私有成员 有没有一种用java实现的方法?如果可能的话,有人能举个例子吗?您不能强制这样做,但您可以在javadoc中创建一个方法和文档 private int myMember; /** * ATTENTION: use this method instead of setting the member directly. */ public void setMyMember(int valu

我想强制类的未来用户也只能通过访问器方法(甚至通过junit或类似的方法)从该类中编写的未来代码访问私有成员


有没有一种用java实现的方法?如果可能的话,有人能举个例子吗?

您不能强制这样做,但您可以在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);
}
private final ThreadLocal成员=new ThreadLocal();
公共void setMember(最终字符串值){
成员集(值);
}

成员字段是最终字段,不能更改。因此,客户端将被迫直接调用setter。

当您谈论在同一个类中进行访问时,它们可以直接访问私有成员,也可以通过访问器方法(如果该成员有)访问私有成员因此,基本上您无法阻止他们直接在同一类中使用成员。

如果您想阻止反射,可以使用SecurityManager。如果这不是一个选项,您可以使用Thread.currentThread().getStackTrace()获取调用堆栈,并检查调用方是否来自您的类

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


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

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


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

利用继承来隐藏字段:

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

只要字段是类的一部分,任何人都可以直接访问它。当我们试图强制所有(合作)作者通过getter/setter时,这可能是一个问题,因为这些方法执行一些转换、检查或簿记工作。与递增内部计数器类似

我想到了一个通用的解决方案:可以使用注释。您必须创建一个注释(以及注释处理器代码),以确保在字段的getter/setter方法之外使用该字段时,这是一个编译时错误:

@GetterSetterAccessOnly
private int value;

如果他们可以访问你的代码,他们可以做任何他们想做的事情。在最坏的情况下,它们会删除你的getter和setter,而只是放在公共字段中;)

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

  • 您应该检查其他人是否应该实现子类,而不是更改类本身。当然,私有字段只能通过setter和getter访问
  • 您可以将数据移动到另一个类中,并使用getter和setter访问另一个类中的数据。这样做只是为了不让数据直接出现在你的类中,这可能有点违反直觉,但因为你可能有一个很好的理由说明他们不应该访问这些数据,这表明了一种不同的责任。因此,无论如何,重构以满足需求是一个好主意

这不会产生任何安全性!查看其他答案。替代解决方案确实创建了安全性。看起来不错,但我们仍然可以从类自身的setter方法之外调用
member.set(“12345”)
。它仍然不强迫人们使用getter/setter方法,但是使用是有限的:“子类”将不能访问“父类”中的其他私有字段。这可能是一个显示阻止程序。请将您希望允许访问的更改为“受保护”!但是,使用getter/setter(更多setter)也是一个好主意,因为您可以执行验证之类的工作。