Package-private class within a .java file - why is

2019-01-24 19:27发布

问题:

Consider the following code, where the HelloWorld class has default or package-private access:

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. So my question is: since HelloWorld is now a package-private class, how does it work? The main() method should not be visible or accessible across packages, am I right?

It makes perfect sense to me if the class HelloWorld is declared public. Confusion is only when it is declared with the default package-private access.

回答1:

JVM startup is described in §12.1 Virtual Machine Start-Up of the JLS.

Note that this chapter says nothing about visibility checks with regards to the class. It only specifies that the main method must be 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"?).



回答2:

Main method won't be visible to other classes which reside in different packages. But the JVM can see it all. 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.



回答3:

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.

The answer is that the Java Language Specification simply does not require the class that contains the main method to be public. 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.

In fact, you can even use a private inner class, and it will still run.



回答4:

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; from the other side - the access could be always got via reflection so it couldn't be treated as a security hole... Anyway e.g. 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.



标签: java jvm package