开发者

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:

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.


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"?).


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.


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜