考虑以下代码,HelloWorld
类具有默认或包私有访问权限:
class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World!"); // Display the string.
}
}
并假设上述代码保存在名为HelloWorld.java
的文件中。所以我的问题是:因为HelloWorld
现在是一个包私有类,它是如何工作的? main()
方法不应该在包中可见或可访问,我是对的吗?
如果将类HelloWorld
声明为公开,那对我来说非常有意义。仅当使用默认的包 - 私有访问声明它时才会出现混淆。
答案 0 :(得分:6)
§12.1 Virtual Machine Start-Up of the JLS中描述了JVM启动。
请注意,本章说明 nothing 有关类的可见性检查。 仅指定main
方法必须为public
。
这意味着根本没有检查类级别的可见性(哪种有意义,因为还没有上下文来检查可见性:“package”是“调用者”?)。
答案 1 :(得分:1)
主方法对于驻留在不同包中的其他类是不可见的。但是JVM可以看到这一切。找到你的主要方法并为你运行它没有任何困难。
如果要模拟访问限制,请在另一个包中编写另一个类,并尝试调用HelloWorld.main
并查看编译器是否保持安静。
答案 2 :(得分:1)
你还没有说清楚,但我认为你的问题是为什么在命令行输入java HelloWorld
时可以运行main方法。
答案是Java Language Specification根本不需要包含main方法的类是公共的。访问修饰符是一种语言机制,主要用于通过封装来帮助维护。它们不是真正的安全功能,当然也不是不可动摇的物理定律。 JVM启动机制只是忽略它们。
事实上,你甚至可以使用私有的内部类,它仍然可以运行。
答案 3 :(得分:1)
可能JLS的设计者决定如果你知道类名,就不需要限制对main方法的访问,而乍一看它看起来反直觉;从另一方面 - 访问可以始终通过反射获得,因此它不能被视为安全漏洞...... 不管怎么说,通过为包私有类创建外观,我们间接访问它...所以保护是由于不正确的使用并允许进一步的更改。