【问题标题】:Why doesn't the class containing main have to be public?为什么包含 main 的类不必是公共的?
【发布时间】:2012-03-27 06:32:03
【问题描述】:

我声明了下面的类

class A { //not public
  public static void main(String args[]) {
     System.out.println("done");
 }

当我编译并运行它时,它运行良好并打印输出“完成”。即使我将其声明为“package a;”中的行为也相同

但是,如果 JVM 规范要求 main 方法应该是公共的,因为“否则它看不到 main”,它不应该也适用于类吗? 如果 JVM 在未声明为 public 时“看不到” A.main(),它如何能够看到 A 类本身。

除了“因为规范是这么说的”之外,还有什么解释吗?

【问题讨论】:

    标签: java


    【解决方案1】:

    JVM 始终可以访问应用程序中的每个类,因为它的职责之一是执行可见性规则。因此,可以得出结论,如果需要,它可以忽略可见性规则(例如,当用户启动应用程序时,JVM 必须找到入口点,即main())。

    换句话说,JVM 不是访问此函数的类,因此不适用可见性。它基本上是监督者,管理从执行到终止的应用程序。

    有关参考,请参阅Execution

    【讨论】:

    • 如果“visibility doesn't apply”,为什么main方法需要public JVM才能访问它,或者将其设置为public 是否只是惯例。
    • @Shashwat 这是 JVM 强制执行的约定。见stackoverflow.com/a/11444861/483349
    【解决方案2】:

    当你声明一个类 private 时,你并没有让它“不可见”,你的方法也是如此。声明一个方法private 仅仅意味着它不能从你的类之外调用。私有类的静态公共方法是可公开调用的。

    【讨论】:

    • 据我所知,包私有(默认访问)类对该包之外的任何类基本上是不可见的。所以它的公共类不能用于该包之外的类。
    【解决方案3】:

    JVM 可以看到非公共类的原因是因为它控制可见性,这意味着它可以看到所有内容并决定什么可以看到/调用/访问什么。

    public 在类上的使用与在方法上的使用不同,但概念是相同的。

    在方法上,public 关键字表示该方法可以在类外使用。一个例子是:

    class A {
      public static void do() {
        // Do something
      }
    }
    
    class B {
      public static void main(String[] args) {
        A.do(); // This works because do() is public and static
      }
    }
    

    同样的概念适用于类,但方式不同。

    在类上使用public 意味着它可以在当前.java 文件之外使用(它将有自己的.class 文件)。

    这是一个例子:

    //C.java
    
      class C {
        static void do() {
          // Do something
        }
    
        public static void run() {
          A.do();  // Works because A.do() is public and static
          B.do();  // Does not work because B is not a public class
        }
      }
    
    
    
    //A.java
    
      public class A {
        public static void main(String[] args) {
          B.do(); // Works because B is in the same file
          do();   // Duh...
        }
    
        public static void do() {
          // Do something
        }
      }
    
      class B {
        static void do() {
          // Do something
        }
      }
    

    【讨论】:

      猜你喜欢
      • 2013-09-08
      • 1970-01-01
      • 2019-12-18
      • 1970-01-01
      • 2018-06-17
      • 2011-11-06
      • 1970-01-01
      • 1970-01-01
      • 2020-04-12
      相关资源
      最近更新 更多