你好世界的工作,但然后得到错误,没有主要的?

我在Java中有以下简单的hello世界:

class A { static { System.out.println("Hello world"); } } 

它按预期工作,但奇怪的是,它给出了一个错误,说主要方法之后不存在。

 $ javac A.java && java A Hello world Exception in thread "main" java.lang.NoSuchMethodError: main 

为什么? 我应该忽略它吗? 我甚至试过制作一个名为“main”的方法,但它什么都没改变。

 class A { static { main(); } public static void main() { System.out.println("Hello world"); } } 

 $ javac A.java && java A Hello world Exception in thread "main" java.lang.NoSuchMethodError: main 

加载类时,将运行static初始化程序,然后JVM将尝试调用main方法。 您可以通过向static初始化程序添加一行来解决此问题:

 public class HelloWorld { static { System.out.println("Look ma', no hands!"); System.exit(0); } } 

这将在尝试调用main方法之前停止JVM。

另请注意,这不会在Java 7中执行.Java 7在初始化类之前查找main方法。

因为你的类是由类加载器加载的,所以执行静态代码,然后它搜索main方法并崩溃,因为它不存在。

包含在任何方法之外的静态块中的类中的代码将在该静态类的第一次引用时执行。

它无法找到您的主要方法的原因是您已经错误地声明了它。 主要看起来像这样:

 public static void main(String[] args){} 

习惯那条线。 你会看到很多次。

String [] args …参数是用户可以通过shell传递给程序的空间描述参数列表。 所有程序都通过main方法进入。 这是传承了一段时间的标准。

可以在类中使用静态块来启动程序,但这会导致混淆并且非常不正确。 使用main方法作为切入点是行业标准。

我无法给出这个标准的原因,或者给出一个更有说服力的论据,为什么要使用它而不是从shell获取对程序的输入。 我不建议从静态块启动程序。

忘记static块,并执行以下操作:

 public static void main(String[] args) { System.out.println("Hello, world!"); } 

你需要一个main方法。 在上一个代码示例中,您已将其定义为错误。 像这样定义:

 public static void main(String[] args) { } 

你错过了args ,这就是为什么它仍然第二次抱怨。

@WilliamMorrison和@Jeffrey解释了为什么你的程序输出“Hello world”然后它崩溃了。

有一个很好的理由使用main而不是你使用static块的方式。 主要是,它是您的计划的切入点。 没有一个,你无法从java命令成功运行程序。 没有一个jar文件就无法执行。 并且,正如你所见,你将会如果你错过了一个主要的,你每次都会得到这个错误,除非你写一个黑客来阻止它(参见@ Jeffrey的回答。我并不是说这是一个冒犯方式,他的答案是非常翔实的,但它是一个黑客IMO)。

另一件事是这不是惯用的。 如果我必须阅读你的代码,我会想,“这个怪异的代码从哪里开始?!” 我无法下载它并弄清楚如何使用我的工具(IDE,maven,ant等)来运行它。 Intellij不知道它可以在没有main方法的情况下运行类。 这是程序的标准切入点。

随机static块不是入口点。 没有办法将参数传递给它。 例如,如果你想编写一个命令行程序,比如unix的“cat”,你传入一个文件名并输出文件内容,你就不能用static块来做,因为没有办法设置和得到输入。

它按预期工作,但奇怪的是:没有类加载。 加载类时,会执行其静态块。

为什么Exception in thread "main" java.lang.NoSuchMethodError: main得到Exception in thread "main" java.lang.NoSuchMethodError: main

因为在第一种情况下你没有主要方法,在第二种情况下签名不正确。

将其更改为public static void main(String a[])

当类被加载到JVM时,它首先“处理”静态块中的内容,这就是它首先打印出“Hello World”的原因,这解释了这一部分:

 class A { static { System.out.println("Hello world"); } } 

当你运行程序时,它会查找“main”方法,因此它首先输出Hello World然后查找main方法,因此错误,当你在静态块中调用方法时应用相同的逻辑。