【问题标题】:What if main method is inside "non public class" of java file?如果 main 方法在 java 文件的“非公共类”中怎么办?
【发布时间】:2012-09-13 12:14:10
【问题描述】:

我有一个包含多个类的 java 文件,其中一个是公共的。如果 main 方法在非公共类中。我无法运行该 java 文件。这是为什么?并且也没有编译错误。如果是这样,我该如何使用该 main 方法?

【问题讨论】:

  • main方法必须能从外部访问。

标签: java main public


【解决方案1】:

实际上你可以在非公共类中执行 main 方法。如果你把这个类

class A {
  public static void main(String... args) {
      System.out.println("This is not a public class!");
  }
}

在一个名为 NonPubClass.java 的文件中。您可以使用 javac 命令编译此文件,但不会得到 NonPubClass.class,而是会得到 A.class。使用 java a 调用该类,您将看到打印的字符串 --- 这不是公共类!

【讨论】:

  • +1。为什么别人都说不能跑非公开类的main方法?也许较旧的 JVM 确实检查了入口类的公共标志?我的 JVM (HotSpot 1.7) 似乎不在乎。
  • @charles_ma 你可以将你的班级命名为NonPubClass 而不是A
【解决方案2】:

看看这段代码:
Super.java

public class Super{ }
class Sub{
    public static void main(String[] s){
        System.out.println("Hello");
    }
}

为了打印Hello,你可以编译和运行程序:

这是如何工作的?
编译器为程序中的每个类生成单独的.class 文件。因此,与其从公共类的main() 调用非公共类的main(),不如打印如上所示的输出。

注意:按照惯例,您必须将public class 放在单独的文件<class_name>.java 中。并且不要将多个类放在一个文件中(除非它们是内部类),因为如果您想导入它们或将它们与其他类一起使用,则会导致问题。

【讨论】:

    【解决方案3】:

    简单的答案。 You can't。您需要在 public class 中有 main 方法,其签名应为 public static void main(String... args)

    没有编译错误

    为什么会有?就编译规则而言,您没有做错任何事。 唯一的问题是您的 non-public-class-main-method 不能作为代码的入口点。

    【讨论】:

    • 没错。为了补充对 OP 问题的答案,没有编译错误是有道理的,因为他正在创建一个名为 main 的方法,这对编译器有效,但如果该方法不在公共类中,则它不会在程序启动。
    • @HernanVelasquez:谢谢。我会在我的答案中添加它。 :)
    • JLS 中哪里说该类必须是公共的?
    • 由于您仍然处于活动状态,能否请您删除此答案? main 方法需要在 public 类中才能使用是不正确的,并且可能会分散没有经验的 Java 用户的注意力,他们不了解它。 (如果该声明在发布时属实,请注意,情况不再如此,至少应更新此答案)。谢谢。
    【解决方案4】:

    我想补充一点,尽管这里的每个人都认为 public 对于类中的 main 是必要的,并且没有 main 它将无法工作

    您可以在一个类中拥有任意数量的主电源,并且您可以在没有公共访问修饰符的情况下拥有它们。 但要小心,只有以文件命名的类才能公开 我的意思是,如果您将文件命名为 a.java ,那么只有名称为 a 的类可以公开,没有其他人可以拥有此功能

    这里有一个代码来显示这个: 如您所见,文件名是help.java

    //:initialization/helping.java
    
    class b{
        public static void main(){
            System.out.println("hello its b");
        }
    }   
    
    class helping {
        static void f(float i, Character... c) {
            System.out.println("first");
        }
        static void f(char a, Character... args) {
            System.out.println("second");
        }
        public static void main(String[] args) {
            f(1,'a');
            f('a','b');
            c.main();
        }
    }
    
    class c{
        public static void main(){
            System.out.println("hello its b");
        }
    }
    //:~
    /*
     * output:  
     * first
     * second
     * hello its b  
     * */
    

    【讨论】:

    • 一个误导性的陈述:“你可以在一个类中拥有任意数量的 mains”——你的意思是在一个 Java 源文件中拥有尽可能多的 mains。每个班级只能有一个主线。您的文件包含三个类。
    【解决方案5】:

    如果顶级类型声明包含以下任一访问修饰符,则会出现编译时错误:protected、private 或 static。此link 可能会有所帮助。

    【讨论】:

      【解决方案6】:

      这不是编译时错误,因为您提到顶级类型声明不应受保护、静态或私有。

      如果你通过你共享的链接http://docs.oracle.com/javase/specs/jls/se7/html/jls-7.html#jls-7.6,那么很明显顶级类型声明仅指“顶级类和接口类型声明”,这些不应该受到保护,静态或私有的顶级声明,但我们可以在其中的任何方法或变量声明中使用受保护的、静态的或私有的。

      以上代码,声明没有错误,所有外部顶级类都是默认的,没有违规,代码会编译运行成功。

      上面的问题的答案与上面几位专家所说的完全一样,

      “当然我们可以在非公共类中拥有一个带有main方法的文件,它会编译并成功运行,但请确保在运行程序时我们必须传递“main”的类名方法”到 java 解释器,而不是公共的类。”

      如果我们有 2 个类 A(public) 和 B(non-public contains main method),那么文件将使用“javac A.java”编译,但在运行代码时,我们需要将命令传递为“java B ”。

      【讨论】:

        【解决方案7】:

        你当然可以重写 main 方法,它不会违反任何编译器规则,因此你不会有任何编译器错误。

        您检查尽管您有多个类,但声明为公共的文件是您尝试执行的文件的名称。

        这是一个约定,文件应以该代码中公开的同一类命名

        因此,当您尝试执行该类时,它没有从其开始执行的 main 方法。因此,如果您想在非公共类中执行 main 方法,唯一的方法是从 main 调用该 main公共类的方法。

        【讨论】:

        • 您不能覆盖静态方法。
        • 答案似乎不正确。首先,正如 Lew Bloch 所指出的,您不能覆盖静态方法,其次,您实际上可以在非公共类中启动 main 方法,而无需按照此处的建议通过公共类。您必须将包含“main”方法的非公共类的名称作为参数传递给“java”命令。
        猜你喜欢
        • 2015-12-17
        • 2011-01-30
        • 1970-01-01
        • 2014-08-28
        • 2016-01-13
        • 2013-09-08
        • 2011-08-24
        • 2012-12-05
        • 2011-03-04
        相关资源
        最近更新 更多