我还没有遇到过由这些关键字引起的编译器错误会使我免于错误的情况。
避免将应用程序作者从错误中保存下来,只是让库作者决定他们承诺维护其实现的哪一部分。
如果我有图书馆
class C {
public void foo() { ... }
private void fooHelper() { /* lots of complex code */ }
}
我可能希望能够替换foo
的实现,并可能fooHelper
以根本性的方式进行更改。如果fooHelper
尽管我的文档中有所有警告,仍然有人决定使用,那么我可能无法做到这一点。
private
使库作者可以将库分解为可管理大小的方法(和private
帮助程序类),而不必担心会被迫将这些内部细节维护多年。
什么使编译器强制实施信息隐藏值得?
附带说明一下,在Java private
中,不是由编译器强制执行,而是由Java 字节码验证程序强制执行。
反射可以覆盖此机制吗?什么使编译器强制实施信息隐藏值得?
在Java中,不仅反射可以覆盖此机制。private
Java 有两种。这种类型private
可防止一个外部类访问private
由字节码验证程序检查的另一个外部类的成员,但也可以private
防止内部类通过包专用的综合访问器方法使用内部对象使用的,
public class C {
private int i = 42;
public class B {
public void incr() { ++i; }
}
}
由于类B
(实名C$B
)使用i
,因此编译器会创建一个综合访问器方法,该方法允许通过字节码验证程序B
进行访问C.i
。不幸的是,由于ClassLoader
允许您从中创建一个类byte[]
,因此C
通过在C
包中创建一个新类(如果C
未密封jar的话),可以很容易地获得暴露给内部类的私有对象。
正确的private
执行要求在类加载器,字节码验证程序和安全策略之间进行协调,以防止反射性访问私有数据。
可以用来保护班级的秘密状态免遭攻击吗?
是。当程序员可以在各自保留其模块安全性的同时进行协作时,“安全分解”是可能的-我不必相信另一个代码模块的作者也不会违反我模块的安全性。
像Joe-E这样的对象功能语言使用信息隐藏和其他方法来使安全分解成为可能:
Joe-E是Java编程语言的子集,旨在根据对象能力准则支持安全编程。Joe-E旨在促进安全系统的构建,并促进对Joe-E中构建的系统的安全性审查。
从该页面链接的论文提供了一个示例,说明如何通过private
强制实施使安全分解成为可能。
提供安全的封装。
图1.仅追加日志记录工具。
public final class Log {
private final StringBuilder content;
public Log() {
content = new StringBuilder();
}
public void write(String s) {
content.append(s);
}
}
考虑图1,图1说明了如何构建仅附加日志工具。假设程序的其余部分是用Joe-E编写的,则代码审阅者可以确信只能添加日志条目,而不能对其进行修改或删除。该检查很实用,因为它只需要检查Log
该类,而不需要检查任何其他代码。因此,验证此属性仅需要有关日志记录代码的本地推理。