Java 静态块是否会在没有main方法的情况下执行?
我试图在我的机器上运行下面的代码,但它没有执行任何操作,也没有显示任何错误Java 静态块是否会在没有main方法的情况下执行?,java,Java,我试图在我的机器上运行下面的代码,但它没有执行任何操作,也没有显示任何错误 public class StaticBlockDemo { static { System.out.println("Hello World"); } } 有人能帮我吗?顺便说一下,我使用的是Java 7。如果在静态-块的末尾放置一个System.exit(0),它将在Java 6及以下版本中运行,不会出现任何错误(没有有效的主!)。这是因为static块是在搜索有效的main方法之前
public class StaticBlockDemo {
static {
System.out.println("Hello World");
}
}
有人能帮我吗?顺便说一下,我使用的是Java 7。如果在
静态
-块的末尾放置一个System.exit(0)
,它将在Java 6及以下版本中运行,不会出现任何错误(没有有效的主
!)。这是因为static
块是在搜索有效的main
方法之前执行的,因此如果在静态块的末尾退出程序,则不会收到任何错误
但是,这种行为在Java7中发生了改变;现在,您必须包含一个显式的main
,即使可能永远无法访问它
在Java7中,问题的答案是false,但在Java6及其以下版本中,答案确实是true
Java 6: Hello World 你好,世界 Java 7: Error: Main method not found in class Test, please define the main method as: public static void main(String[] args) 错误:在类测试中找不到主方法,请将主方法定义为: 公共静态void main(字符串[]args)
静态块在类初始化时执行。通常,
main
类将导致引导类的初始化,但也有其他方法引导程序,例如通过VM
调用类的static main
方法会导致其初始化,但其他许多事情也是如此:
public class Foo {
static { System.out.println("Foo initialized"); }
public static void main(String... argv) {
Initialized.callingThisCausesClassInitialization();
}
static class Initialized {
static { System.out.println("Initialized initialized"); }
static void callingThisCausesClassInitialization() {}
}
static class NotInitialized {
static { System.out.println("NotInitialized initialized"); }
static void callingThisCausesClassInitialization() {}
}
}
运行foo将打印
Foo initialized
Initialized initialized
它不会打印
NotInitialized initialized
因为在程序的执行过程中没有做任何导致其初始化的事情
您的类似乎有这种行为,因为它从未被使用过,如上面的
NotInitialized
。投票最多的答案是“大部分”正确,但并非完全正确。
考虑下面的代码,其中类有主方法和静态方法。静态方法将(成功地)在主方法和构造函数之前执行,并生成序列:abcd-这与您可能认为的不同
public class Sequence {
Sequence() {
System.out.print("c ");
}
{
System.out.print("B ");
}
public static void main(String[] args) {
new Sequence().go();
}
void go() {
System.out.print("D ");
}
static{
System.out.print("A ");
}
}
这个解释很详细,但我把它抽象为这个具体问题 首先,当类在运行时而不是编译时第一次引用它时,类加载器子系统将加载该类。 因此,类加载器本身是java.lang包中的一个类,并且 它的实例称为加载类的类装入器实例 现在来详细介绍一下,它遵循一个层次结构,引导类加载器位于顶部 注意,引导类加载器本身是类加载器的一个实例 此外,这些实例还执行验证、准备和解析符号引用,以保持简单。它执行java程序的动态链接 现在,当编译器编译.java文件时,它会插入一个Class类型的公共静态final字段 您可以在java.lang.Class obj=name\u of\u your\u Class.Class中访问它 它包含一个getClassLoader方法,告诉加载这个类的classLoader实例 只有使用这些信息,类加载器才能知道要加载的类的名称,即它的完全限定名(package.class) 在本机文件系统中搜索文件并加载之前 它通过其父实例检查它是否已经加载了该文件,并且该检查会一直传播到top BootclassLoader 只有当它们都没有加载该类文件时,才只有该实例加载该类文件。 在这种情况下,这些事情如何发生的细节无关紧要 一旦类被加载,静态块将在类加载器子系统的初始化阶段执行 因为我已经告诉过编译器,它扮演着插入那个字段的角色。 请注意,找不到main方法是一个运行时错误,因此编译器对此不负责任,而是JVM 在Java7中,main方法是在之前搜索的,如果没有,我们会在运行时得到这个错误 但是在Java6和更早的版本中,当类加载发生时,静态块被执行,然后它进行搜索以找到主方法,但是如果我们提供System.exit(0);在块中,它甚至在进行搜索之前终止程序,因此我们没有任何错误 尽管在java 7中,对主方法的探测是在执行静态块之前完成的,但静态块的执行本身取决于对主方法的成功发现。即使程序的执行顺序与java 6和早期版本中的相同 更详细地说,要放置在堆栈本身上的第一个元素应该是主线程。 我们知道执行控制是如何流动的,需要注意的是,静态块即使包含块的局部变量,也不会作为激活记录放在堆栈上,而是放在方法区域上。 因此,从Java7开始,JVM检查堆栈上是否存在主线程记录,然后将控制权交给静态块,然后按顺序执行所有静态块。而在Java6和更早版本中,它做了相反的事情 还需要注意的是,我们不能将静态块嵌套在任何静态或非静态范围内,因为该块的封闭范围仅为类的封闭范围
我甚至知道理解它有点棘手,但是阅读这个答案肯定会对静态块有很好、准确和深入的理解。在java 8中,如果不显式地编写main方法,就无法运行程序。从这个角度来看,答案是错误的。没有main方法,静态块不会执行。下面是一段代码,显示了初始化的顺序。(Static block==>main==>initialization bloc)
public class Sequence {
Sequence() {
System.out.print("c ");
}
{
System.out.print("B ");
}
public static void main(String[] args) {
new Sequence().go();
}
void go() {
System.out.print("D ");
}
static{
System.out.print("A ");
}
}
public class StaticBlock {
static{
System.out.println("in static block");
}
{
System.out.println("in initialization block");
}
public StaticBlock(){
System.out.println("in const");
}
public static void main(String[] args) {
System.out.println("in main method");
StaticBlock block=new StaticBlock();
}
abstract class test extends javafx.application.Application {
static {
System.out.println(“hello”);
System.exit(0);
}
}