简体   繁体   English

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

[英]Package-private class within a .java file - why is it accessible?

Consider the following code, where the HelloWorld class has default or package-private access: 请考虑以下代码,其中HelloWorld类具有默认或包私有访问权限:

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

And assume that the above code is saved in a file called HelloWorld.java . 并假设上面的代码保存在一个名为HelloWorld.java的文件中。 So my question is: since HelloWorld is now a package-private class, how does it work? 所以我的问题是:既然HelloWorld现在是一个包私有类,它是如何工作的? The main() method should not be visible or accessible across packages, am I right? main()方法不应该在包中可见或可访问,对吗?

It makes perfect sense to me if the class HelloWorld is declared public. 如果类HelloWorld被声明为public,那对我来说非常有意义。 Confusion is only when it is declared with the default package-private access. 仅当使用默认的包 - 私有访问声明它时才会出现混淆。

JVM startup is described in §12.1 Virtual Machine Start-Up of the JLS . JVM启动在§12.1JLS的虚拟机启动中描述。

Note that this chapter says nothing about visibility checks with regards to the class. 请注意,本章没有提及有关类的可见性检查。 It only specifies that the main method must be public . 它只规定了main 方法必须是public

This means that there simply is no check for visibility on the class level (which kind-of makes sense as there is no context yet against which to check the visibility: in which "package" is the "caller"?). 这意味着根本没有检查类级别的可见性(哪种有意义,因为还没有上下文来检查可见性:“package”是“调用者”?)。

Probably the designers of JLS decided there is no need to restrict access to main method if you know the class name, while at the first glance it looks counter-intuitive; 可能JLS的设计者决定如果你知道类名,就不需要限制对main方法的访问,而乍一看它看起来反直觉; from the other side - the access could be always got via reflection so it couldn't be treated as a security hole... Anyway eg by creating facade to a package-private class we access that one indirectly... So the protection is rather from incorrect usage and to allow further changes. 从另一方面 - 访问可以总是通过反射得到,所以它不能被视为一个安全漏洞...无论如何,例如通过创建一个包私有类的外观,我们间接访问那个...所以保护是而是来自不正确的使用并允许进一步的更改。

Main method won't be visible to other classes which reside in different packages. 主方法对于驻留在不同包中的其他类是不可见的。 But the JVM can see it all. 但是JVM可以看到这一切。 It won't have any difficulty in finding your main method and running it for you. 找到您的主要方法并为您运行它不会有任何困难。

If you want to simulate the access restriction, write another class in a different package and try to call HelloWorld.main and see if the compiler keeps quiet. 如果要模拟访问限制,请在另一个包中编写另一个类,并尝试调用HelloWorld.main并查看编译器是否保持安静。

You have not made it very clear, but I assume that your question is why that main method can be run when you type java HelloWorld at the command line. 你还没有说清楚,但我认为你的问题是为什么在命令行输入java HelloWorld时可以运行main方法。

The answer is that the Java Language Specification simply does not require the class that contains the main method to be public. 答案是Java语言规范只是不要求包含main方法的类是公共的。 Access modifiers are a language mechanism mainly intended to help maintainability via encapsulation. 访问修饰符是一种语言机制,主要用于通过封装来帮助维护。 They're not really a security feature, and certainly not unshakable laws of physics. 它们不是真正的安全功能,当然也不是不可动摇的物理定律。 The JVM startup mechanism simply ignores them. JVM启动机制只是忽略它们。

In fact, you can even use a private inner class, and it will still run. 实际上,您甚至可以使用私有内部类,它仍然可以运行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM