%JAVA_HOME%/lib 中存在 tools.jar,无意中发现其中的 javac的代码实现如下:
package com.sun.tools.javac;
import com.sun.tools.javac.util.Version;
import java.io.PrintWriter;
import java.lang.reflect.Method;
@Version("@(#)Main.java\t1.25 06/04/30")
public class Main
{
public static void main(String[] paramArrayOfString)
throws Exception
{
if ((paramArrayOfString.length > 0) && (paramArrayOfString[0].equals("-Xjdb"))) {
String[] arrayOfString = new String[paramArrayOfString.length + 2];
Class localClass = Class.forName("com.sun.tools.example.debug.tty.TTY");
Method localMethod = localClass.getDeclaredMethod("main", new Class[] { paramArrayOfString.getClass() });
localMethod.setAccessible(true);
System.arraycopy(paramArrayOfString, 1, arrayOfString, 3, paramArrayOfString.length - 1);
arrayOfString[0] = "-connect";
arrayOfString[1] = "com.sun.jdi.CommandLineLaunch:options=-esa -ea:com.sun.tools...";
arrayOfString[2] = "com.sun.tools.javac.Main";
localMethod.invoke(null, new Object[] { arrayOfString });
} else {
System.exit(compile(paramArrayOfString));
}
}
public static int compile(String[] paramArrayOfString)
{
com.sun.tools.javac.main.Main localMain = new com.sun.tools.javac.main.Main("javac");
return localMain.compile(paramArrayOfString);
}
public static int compile(String[] paramArrayOfString, PrintWriter paramPrintWriter)
{
com.sun.tools.javac.main.Main localMain = new com.sun.tools.javac.main.Main("javac", paramPrintWriter);
return localMain.compile(paramArrayOfString);
}
static
{
ClassLoader localClassLoader = Main.class.getClassLoader();
if (localClassLoader != null)
localClassLoader.setPackageAssertionStatus("com.sun.tools.javac", true);
}
}
其中通过获取当前类加载器的实例进行指定断言开启
ClassLoader localClassLoader = Main.class.getClassLoader();
if (localClassLoader != null)
localClassLoader.setPackageAssertionStatus("com.sun.tools.javac", true);
并且通过该类的main方法中调用另外一个可以作为入口类的main方法的过程,可以猜想jvm在启动的时候通过指定入口类其调用方式应该也是一致的
Class localClass = Class.forName("com.sun.tools.example.debug.tty.TTY");
Method localMethod = localClass.getDeclaredMethod("main", new Class[] { paramArrayOfString.getClass() });
...