public class Test { static int A = 10; static { A = 20; } } class Test1 extends Test { private static int B = A; public static void main(String[] args) { System.out.println(Test1.B); } } //输出结果 //20
public interface InterfaceInitTest { long A = CurrentTime.getTime(); } interface InterfaceInitTest1 extends InterfaceInitTest { int B = 100; } class InterfaceInitTestImpl implements InterfaceInitTest1 { public static void main(String[] args) { System.out.println(InterfaceInitTestImpl.B); System.out.println("---------------------------"); System.out.println("当前时间:" InterfaceInitTestImpl.A); } } class CurrentTime { static long getTime() { System.out.println("加载了InterfaceInitTest接口"); return System.currentTimeMillis(); } } //输出结果 //100 //--------------------------- //加载了InterfaceInitTest接口 //当前时间:1560158880660
public class MultiThreadInitTest { static int A = 10; static { System.out.println(Thread.currentThread() "init MultiThreadInitTest"); try { TimeUnit.SECONDS.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) { Runnable runnable = () -> { System.out.println(Thread.currentThread() "start"); System.out.println(MultiThreadInitTest.A); System.out.println(Thread.currentThread() "run over"); }; Thread thread1 = new Thread(runnable); Thread thread2 = new Thread(runnable); thread1.start(); thread2.start(); } } //输出结果 //Thread[main,5,main]init MultiThreadInitTest //Thread[Thread-0,5,main]start //10 //Thread[Thread-0,5,main]run over //Thread[Thread-1,5,main]start //10 //Thread[Thread-1,5,main]run over
public class StaticInnerSingleton { /** * 使用静态内部类实现单例: * 1:线程安全 * 2:懒加载 * 3:非反序列化安全,即反序列化得到的对象与序列化时的单例对象不是同一个,违反单例原则 */ private static class LazyHolder { private static final StaticInnerSingleton INNER_SINGLETON = new StaticInnerSingleton(); } private StaticInnerSingleton() { } public static StaticInnerSingleton getInstance() { return LazyHolder.INNER_SINGLETON; } }
public class Tester { static { System.out.println("Tester类的静态初始化块"); } } class ClassLoaderTest { public static void main(String[] args) throws ClassNotFoundException { ClassLoader classLoader = ClassLoader.getSystemClassLoader(); //下面语句仅仅是加载Tester类 classLoader.loadClass("loader.Tester"); System.out.println("系统加载Tester类"); //下面语句才会初始化Tester类 Class.forName("loader.Tester"); } } //输出结果 //系统加载Tester类 //Tester类的静态初始化块
public class BootstrapTest { public static void main(String[] args) { //获取根类加载器所加载的全部URL数组 URL[] urLs = Launcher.getBootstrapClassPath().getURLs(); Arrays.stream(urLs).forEach(System.out::println); } } //输出结果 //file:/C:/SorftwareInstall/java/jdk/jre/lib/resources.jar //file:/C:/SorftwareInstall/java/jdk/jre/lib/rt.jar //file:/C:/SorftwareInstall/java/jdk/jre/lib/sunrsasign.jar //file:/C:/SorftwareInstall/java/jdk/jre/lib/jsse.jar //file:/C:/SorftwareInstall/java/jdk/jre/lib/jce.jar //file:/C:/SorftwareInstall/java/jdk/jre/lib/charsets.jar //file:/C:/SorftwareInstall/java/jdk/jre/lib/jfr.jar //file:/C:/SorftwareInstall/java/jdk/jre/classes
public class ClassloaderPropTest { public static void main(String[] args) throws IOException { //获取系统类加载器 ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); System.out.println("系统类加载器:" systemClassLoader); /* 获取系统类加载器的加载路径——通常由CLASSPATH环境变量指定,如果操作系统没有指定 CLASSPATH环境变量,则默认以当前路径作为系统类加载器的加载路径 */ Enumeration<URL> eml = systemClassLoader.getResources(""); while (eml.hasMoreElements()) { System.out.println(eml.nextElement()); } //获取系统类加载器的父类加载器,得到扩展类加载器 ClassLoader extensionLoader = systemClassLoader.getParent(); System.out.println("系统类的父加载器是扩展类加载器:" extensionLoader); System.out.println("扩展类加载器的加载路径:" System.getProperty("java.ext.dirs")); System.out.println("扩展类加载器的parant:" extensionLoader.getParent()); } } //输出结果 //系统类加载器:sun.misc.Launcher$AppClassLoader@18b4aac2 //file:/C:/ProjectTest/FengKuang/out/production/FengKuang/ //系统类的父加载器是扩展类加载器:sun.misc.Launcher$ExtClassLoader@1540e19d //扩展类加载器的加载路径:C:\SorftwareInstall\java\jdk\jre\lib\ext;C:\WINDOWS\Sun\Java\lib\ext //扩展类加载器的parant:null
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { synchronized (getClassLoadingLock(name)) { //第一步,先从缓存里查看是否已经加载 Class<?> c = findLoadedClass(name); if (c == null) { long t0 = System.nanoTime(); try { //第二步,判断父加载器是否为null if (parent != null) { c = parent.loadClass(name, false); } else { c = findBootstrapClassOrNull(name); } } catch (ClassNotFoundException e) { // ClassNotFoundException thrown if class not found // from the non-null parent class loader } if (c == null) { //第三步,如果前面都没有找到,就会调用findClass方法 long t1 = System.nanoTime(); c = findClass(name); // this is the defining class loader; record the stats sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0); sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1); sun.misc.PerfCounter.getFindClasses().increment(); } } if (resolve) { resolveClass(c); } return c; } }
public class Hello { public void test(String str){ System.out.println(str); } } public class MyClassloader extends ClassLoader { /** * 读取文件内容 * * @param fileName 文件名 * @return */ private byte[] getBytes(String fileName) throws IOException { File file = new File(fileName); long len = file.length(); byte[] raw = new byte[(int) len]; try (FileInputStream fin = new FileInputStream(file)) { //一次性读取Class文件的全部二进制数据 int read = fin.read(raw); if (read != len) { throw new IOException("无法读取全部文件"); } return raw; } } @Override protected Class<?> findClass(String name) throws ClassNotFoundException { Class clazz = null; //将包路径的(.)替换为斜线(/) String fileStub = name.replace(".", "/"); String classFileName = fileStub ".class"; File classFile = new File(classFileName); //如果Class文件存在,系统负责将该文件转换为Class对象 if (classFile.exists()) { try { //将Class文件的二进制数据读入数组 byte[] raw = getBytes(classFileName); //调用ClassLoader的defineClass方法将二进制数据转换为Class对象 clazz = defineClass(name, raw, 0, raw.length); } catch (IOException e) { e.printStackTrace(); } } //如果clazz为null,表明加载失败,抛出异常 if (null == clazz) { throw new ClassNotFoundException(name); } return clazz; } public static void main(String[] args) throws Exception { String classPath = "loader.Hello"; MyClassloader myClassloader = new MyClassloader(); Class<?> aClass = myClassloader.loadClass(classPath); Method main = aClass.getMethod("test", String.class); System.out.println(main); main.invoke(aClass.newInstance(), "Hello World"); } } //输出结果 //Hello World