.java文件中的包私有类 – 为什么它可以访问?

请考虑以下代码,其中HelloWorld类具有默认或包私有访问权限:

 class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); // Display the string. } } 

并假设上面的代码保存在一个名为HelloWorld.java的文件中。 所以我的问题是:因为HelloWorld现在是一个包私有类,它是如何工作的? main()方法不应该在包中可见或可访问,对吗?

如果类HelloWorld被声明为public,那对我来说非常有意义。 仅当使用默认的包 – 私有访问声明它时才会出现混淆。

JVM启动在§12.1JLS的虚拟机启动中描述。

请注意,本章未提及有关类的可见性检查。 它只指定main 方法必须是public

这意味着根本没有检查类级别的可见性(哪种有意义,因为还没有上下文来检查可见性:“package”是“调用者”?)。

主要方法对于驻留在不同包中的其他类是不可见的。 但是JVM可以看到这一切。 找到您的主要方法并为您运行它不会有任何困难。

如果要模拟访问限制,请在另一个包中编写另一个类,并尝试调用HelloWorld.main并查看编译器是否保持安静。

你还没有说清楚,但我认为你的问题是为什么在命令行输入java HelloWorld时可以运行main方法。

答案是Java语言规范只是不要求包含main方法的类是公共的。 访问修饰符是一种语言机制,主要用于通过封装帮助维护。 它们不是真正的安全function,当然也不是不可动摇的物理定律。 JVM启动机制只是忽略它们。

实际上,您甚至可以使用私有内部类,它仍然可以运行。

可能JLS的设计者决定如果你知道类名,就不需要限制对main方法的访问,而乍一看它看起来反直觉; 从另一方面 – 访问可以总是通过reflection获得,因此它不能被视为安全漏洞……无论如何,例如通过创建一个包私有类的外观,我们间接访问那个…所以保护是而是来自不正确的使用并允许进一步的更改。