18

我用一个静态块编写了一个简单的类

class Hello
{

  static {
           System.out.println("Hello");
       System.exit(0);
     }
}

当我使用 jdk1.5 运行它时,正在执行静态块

C:\apps\Java\jdk1.5.0_21\bin>javac Hello.java

C:\apps\Java\jdk1.5.0_21\bin>
C:\apps\Java\jdk1.5.0_21\bin>
C:\apps\Java\jdk1.5.0_21\bin>
C:\apps\Java\jdk1.5.0_21\bin>java Hello

Hello

但是当我使用 jdk1.7 运行它时,我收到以下错误

C:\Program Files (x86)\Java\jdk1.7.0_02\bin>
C:\Program Files (x86)\Java\jdk1.7.0_02\bin>javac Hello.java

C:\Program Files (x86)\Java\jdk1.7.0_02\bin>java Hello
Error: Main method not found in class Hello, please define the main method as:
    public static void main(String[] args)

任何人都可以对 JDK 5 和 JDK 7 中的这种行为变化有任何想法吗?

提前致谢!!

4

9 回答 9

24

Java 7 在加载类之前会寻找一个 main 方法。这是与以前的 java 版本相比的行为更改,因此您的静态块没有执行。在以前的版本中,行为是 JRE 用于在加载类后和执行静态块后查找 main 方法。

于 2013-07-06T06:51:59.670 回答
11

是的,在 jdk7 中。静态块不会首先执行。它首先在应用程序中查找入口点。

因此,它首先检查public static void main(String a[]),如果此方法不存在,则不会执行静态块。

于 2013-07-06T06:52:40.323 回答
6

通过JLS 12.1

Java 虚拟机通过调用某个指定类的 main 方法开始执行,并传递给它一个参数,该参数是一个字符串数组。在本规范的示例中,第一类通常称为测试。

执行 Test 类的 main 方法的初始尝试发现未加载类 Test - 也就是说,Java 虚拟机当前不包含此类的二进制表示。Java 虚拟机然后使用类加载器来尝试找到这样的二进制表示。

Java 7 查找public static main(String[] args)方法,这是应用程序的入口点,然后加载类,这与 Java 6 加载类然后查找main方法不同。

于 2013-07-06T07:00:01.027 回答
3

您可能需要public static void main(String[] args){ }在 JDK7 的类中放置方法。在 JDK7 中,在静态块之前检查 main 方法的存在,如果它没有找到,则会出现异常。

于 2013-07-06T06:49:15.767 回答
1

如果您仔细阅读 JLS 第 12 章(版本 5 或 7),则没有指定“主”类的静态初始化应该何时发生。确实有一个错误报告抱怨这一点。

指定的是在调用入口点方法之前初始化“主”类(并且将运行静态初始化程序) 。这是在JLS 12.4.1中指定的

我无法解释他们为什么要更改此内容,也无法找到他们记录更改的位置。但显然它确实改变了。如果您想要真正的解释,您需要询问负责的 Sun / Oracle 工程师。

(FWIW,我认为这是一个很好的变化。发生静态初始化然后由于找不到入口点而导致程序失败是意外行为,如果没有充分的理由,意外是不好的。)

于 2013-07-06T07:43:56.583 回答
1

程序不会执行,因为从 JDK 1.7 开始,如果您的程序没有具有正确签名的 main 方法,但静态块和方法将始终首先执行,oracle 对静态块和静态变量调用方法进行了限制。作为内存管理静态变量在类加载时完成。

于 2013-07-06T07:27:49.377 回答
0

除非它是一个小程序或其他东西,否则你不能在没有main方法的情况下执行一个 java 程序。我说你对 jdks 的观察可能是错误的

于 2013-07-06T06:52:49.937 回答
0

最高JDK1.6:-

它首先加载类,并在加载类时执行静态块。然后检查要执行的主要方法。

JDK1.7 以上:

它首先检查 main 方法是否可用。

if available
   then first execute static and
   then main method will be executed.

if not available
throw error 
于 2014-08-07T07:05:43.117 回答
0

java 1.7之前的静态块是在main方法之前执行的,所以我们可以在没有main方法的情况下执行代码,从JDK 1.7开始,没有main方法是不可能执行静态块的,因为编译器在类文件中寻找main方法。

因此,当我们要在 JDK 1.7 以上执行代码时,它会显示错误:在类 hello 中找不到主方法,请将主方法定义为:public static void main(String[] args) 或 JavaFX 应用程序类必须扩展 javafx.application 。应用

于 2018-11-09T09:42:57.887 回答