我写了一个带有一个静态块的简单类
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中的这种行为变化有所了解吗?
提前致谢!!
答案 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抱怨这个。
指定的是
我无法解释为什么他们改变了这一点,或者找到他们记录变化的地方。但显然它做了改变。如果您想要真正的解释,您需要向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