我是Java的初学者。我学到的第一件事是可执行类的main()方法应该是 public ,并且给出的原因是因为这个方法将被 JVM 调用它应该是可见的课外,因此应该是公开的。现在,在研究序列化时,我发现JVM在序列化和反序列化对象时可以调用writeObject()
类的readObject()
和Serializable
私有方法!如果它们是私有方法,那么JVM如何调用它们?如果它可以为什么它不能调用main()方法?
翻阅了一些java文档后,我读到了这一行" JVM可以访问对象的私有方法" 。因为我们使用ObjectInputStream的实例调用readObject(),所以JVM可以访问它,而main()方法是静态或类方法,并且在没有实例化类的任何对象的情况下调用应该是公共的,以便JVM可以访问!那有意义吗 ?我不知道。
答案 0 :(得分:4)
关于惯例。 JVM可以在任何地方调用每个方法 - 它是JVM,Boss。如果JVM无法调用它,那么没有人可以。想象一下,JVM是你的程序被执行的地方,它是你和你的字节码之间的某种代理。
writeObject可能在您的课外没有用。这是一种内部唯一的方法,仅适合您。因此,JVM的制造商同意将其保密。如果它不是私有的,程序中的其他类就可以调用它。
main()方法是一个可能被其他Java进程调用的方法。如果是私人的,其他程序无法启动您的程序。它与JVM没什么关系,除了你可以说通常JVM允许你(!)只调用代码的公共(包,受保护)方法。
答案 1 :(得分:2)
总的来说,我同意@Christian,但我还有2个注释:
main()函数也可以是私有的。
如果确实需要,您也可以调用私人方法/功能。
1 JVM无论如何都可以调用main()。将其公开使您的应用程序的另一个代码也可以调用main()方法。但是,通常情况下,没有人这样做。 main()为公开的主要原因是历史性的,AFAIC。其他程序语言也有main()函数,并且是公共的。
2如果您确实需要,可以使用Core Reflection API来调用私有方法或访问私有字段。它看起来像这样:
import java.lang.reflect.Field;
class SimpleKeyPair {
private String privateKey = "Cafe Babe"; // private field
}
public class PrivateMemberAccessTest {
public static void main(String[] args) throws Exception {
SimpleKeyPair keyPair = new SimpleKeyPair();
Class c = keyPair.getClass();
// get the reflected object
Field field = c.getDeclaredField("privateKey");
// set accessible true
field.setAccessible(true);
// prints "Cafe Babe"
System.out.println("Value of privateKey: " + field.get(keyPair));
// modify the member varaible
field.set(keyPair, "Java Duke");
// prints "Java Duke"
System.out.println("Value of privateKey: " + field.get(keyPair));
}
}