2

这是我的代码:

public class Test
{
   static 
   {
      main(null);
   }
   public static void main(String [] args)
   {
      System.out.println("done");
   }
}

我得到以下输出:

done 
done

有人可以解释一下原因吗?

4

7 回答 7

6

原因是它main被调用了两次:

  1. 明确地,一旦加载类,就从静态初始化块开始。
  2. 隐含地,在程序启动后立即进入程序。

如何解决这个问题?要么不显式调用它,要么重命名它,这样它就不会被自动调用。

于 2012-04-10T20:14:26.717 回答
3

你觉得什么不寻常?该static块在加载类时执行一次(并且必须在执行方法之前加载它main。然后执行main方法本身。

看看这个修改后的版本:

public class Test {
    static {
        main(new String[]{"[done static]"});
    }

    public static void main(String[] args) {
        System.out.println(args.length > 0 ? args[0] : "[done]");
    }
}

它打印:

[done static]
[done]
于 2012-04-10T20:14:58.947 回答
2

因为

  • static { ... }当类在 JVM 中加载时调用该部分Test(它是一种静态构造函数)
  • 而在main执行开始时调用该方法。
于 2012-04-10T20:14:44.620 回答
1

类的静态块在类首次加载时被调用。这是第一个完成的。第二个是因为您正在运行程序,然后调用了 main 方法。

于 2012-04-10T20:14:30.227 回答
1

虚拟机在加载 jar 时会自动调用 main。所以这是第一个“完成”,Java 程序的正常入口点。

编写第二个“完成”是因为您在静态类初始化程序中显式调用它。一旦你的类被虚拟机类加载器加载,你添加到“测试”类的“静态”部分就会被调用。

甚至应该在调用入口点 Main 之前调用静态初始化程序中的那个,因为需要在调用入口点之前加载类。

于 2012-04-10T20:16:00.887 回答
1

在调用之前Test.main,JVM 需要Test通过运行其静态初始化程序来初始化该类。此调用负责第一次调用main(). 初始化完成后,JVM 再次调用main(),最终生成您看到的输出。

于 2012-04-10T20:16:32.560 回答
1

Main 由 JVM 自动调用。不需要在静态部分中调用它。

public class Test
{
   public static void main(String [] args)
   {
      System.out.println("done");
   }
}

上面的代码应该是这样的。

于 2012-04-10T20:19:11.153 回答