我对序列化有疑问。如果我的类有私有变量并且没有getter和setter,那么Serialization API将如何读取这些变量的值。
答案 0 :(得分:13)
首先,访问权限是编译时功能。访问不在运行时控制。
可能会让您感到困惑,但请尝试执行以下操作: 创建A类的2个版本:
public class A {
public foo() {
System.out.println("hello");
}
}
public class A {
private foo() {
System.out.println("hello");
}
}
现在编写调用新A()。foo()的类,并使用类A的第一个版本编译它。然后将第二个版本放入类路径并运行应用程序。它会工作!
所以,不要担心访问权限:它们总是被绕过。
例如,如果您使用反射调用私有方法foo()
,则必须获取方法,然后调用setAccessible(true)
:
Method m = A.class.getMethod("foo",
null); m.setAccessible(true);
m.invoke(new A(), null);
如果我们可以从代码中访问私有方法,请确保JDK类即使用java编写也可以执行此操作。 BTW据我所知,标准的java序列化是作为本机代码实现的。
答案 1 :(得分:12)
Serialization API不担心私有变量。其目的是将您的对象转换为文件中的二进制表示形式或稍后可以重建的其他类型的存储。
Here是Java的序列化算法。
答案 2 :(得分:5)
默认的序列化机制不关心成员变量的访问范围。换句话说,public,protected,package-private和private变量都以相同的方式处理。实现细节可能会有所不同,但我记得Sun JRE通过在本机(JNI)代码中实现大部分序列化来实现这一点,其中不强制执行访问权限。
答案 3 :(得分:4)
不要担心,通过使用反映,任何人都可以访问您的私人字段。
Here是一个如何执行此操作的示例。