静态块未在JDK 7中执行,“未找到主方法”,但在JDK 1.5中有效

时间:2013-07-06 06:45:54

标签: java

我写了一个带有一个静态块的简单类

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中的这种行为变化有所了解吗?

提前致谢!!

9 个答案:

答案 0 :(得分:24)

Java 7在加载类之前查找main方法。这是以前java版本的行为更改,因此您的静态块未执行。 在以前的版本中,行为是JRE用于在加载类后以及执行静态块之后查找main方法。

答案 1 :(得分:11)

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

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

答案 2 :(得分:6)

浏览JLS 12.1

  

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

     

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

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

答案 3 :(得分:3)

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

答案 4 :(得分:1)

程序没有执行,因为从JDK 1.7 oracle已经对静态块和静态变量调用方法施加了限制,如果你的程序没有正确签名的主方法,但静态块和方法将永远是首先执行。由于静态变量的内存管理是在类加载时完成的。

答案 5 :(得分:1)

如果您仔细阅读JLS第12章(版本5或7),则不会在“main”类的静态初始化发生时指定。确实有一个Bug Report抱怨这个。

指定的是

类将在调用入口点方法之前初始化(并且将运行静态初始化程序)。这在JLS 12.4.1

中指定

我无法解释为什么他们改变了这一点,或者找到他们记录变化的地方。但显然它做了改变。如果您想要真正的解释,您需要向Sun / Oracle工程师负责。

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

答案 6 :(得分:0)

如果没有 main 方法,则无法执行java程序,除非它是applet或其他内容。我说你对jdks的观察可能是错误的

答案 7 :(得分:0)

高达JDK1.6: -

首先加载类,然后加载类静态块将被执行。 然后检查要执行的主要方法。

JDK1.7以后:

首先检查主要方法是否可用。

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

if not available
throw error 

答案 8 :(得分:0)

在Java 1.7静态块在main方法之前执行之前,因此我们可以在没有main方法的情况下执行代码,由于JDK 1.7,没有main方法就无法执行static bock,因为编译器正在类文件中寻找main方法

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