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

时间:2013-07-05 21:04:08

标签: java static

我在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

6 个答案:

答案 0 :(得分:23)

加载类后,将运行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方法。

答案 1 :(得分:11)

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

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

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

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

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

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

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

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

答案 2 :(得分:8)

忘记static块,并按照以下步骤操作:

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

答案 3 :(得分:5)

您确实需要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块来执行,因为没有设置和获取输入的方式。

答案 4 :(得分:2)

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

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

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

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

答案 5 :(得分:1)

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

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

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