Test classes to be loaded:
Package JVM; public class TestClass {// private static TestClass tc = new TestClass (); public static int I = 23; public static int j = 1; // initialization results may also be affected if the order is different. class initialization is top-down during class loading. Therefore, after initialization, I and j have different private static TestClass tc = new TestClass () values (); // if it is initialized again, I and j will all add 1 private static TestClass tc2 = new TestClass (); public TestClass () {I ++; j ++ ;} public static TestClass getInstance () {return tc ;}@ Overridepublic String toString () {return "I =" + I + "; j =" + j ;}}
Self-compiled class loaders:
Package JVM; import java. io. byteArrayOutputStream; import java. io. fileInputStream; import java. io. inputStream; public class ClassLoaderTest extends ClassLoader {public ClassLoaderTest (ClassLoader cl) {super (cl);} public ClassLoaderTest () {super () ;}@ Overrideprotected Class <?> FindClass (String name) throws ClassNotFoundException {byte [] B = loadClassData (name); String nameClasss [] = name. split ("[/\.] "); // The relative path String nameClass =" JVM. "+ nameClasss [nameClasss. length-2]; return defineClass (nameClass, B, 0, B. length) ;}@ Overridepublic Class <?> LoadClass (String name) throws ClassNotFoundException {return super. loadClass (name);} private byte [] loadClassData (String name) {byte [] B = null; try {InputStream in = new FileInputStream (name ); byteArrayOutputStream bos = new ByteArrayOutputStream (); byte [] bs = new byte [1024]; int len; while (len = in. read (bs ))! =-1) {bos. write (bs, 0, len);} B = bos. toByteArray (); in. close (); bos. close ();} catch (Exception e) {e. printStackTrace ();} return B ;}}
Externally load the TestClass. class file:
Package JVM; public class MyMain {/*** @ param args * @ throws IllegalAccessException * @ throws InstantiationException */public static void main (String [] args) throws Exception {/*** initialize the TestClass object and the result is I = 24; j = 2 * // TestClass tc = TestClass. getInstance (); // System. out. println (tc);/*** use the system loader to load TestClass and the result is I = 25; j = 3 * First initialize TestClass tc = new TestClass () * initialize TestClass through the Class Loader for the second time */ClassLoaderTest clt = ne W ClassLoaderTest (ClassLoader. getSystemClassLoader (); // ClassLoaderTest clt = new ClassLoaderTest (null); // ClassLoaderTest clt = new ClassLoaderTest (ClassLoader. getSystemClassLoader (); // Class clazz = clt. loadClass ("JVM. testClass "); // obtain the current java path System. out. println (MyMain. class. getResource (""). toString (). substring (6); Class clazz = clt. loadClass (MyMain. class. getResource (""). toString (). substring (6) + "TestClass. Class "); ClassLoader cl = clt; System. out. println ("TestClass loader is" + clt); System. out. println ("the current loader is" + ClassLoader. getSystemClassLoader (); while (cl! = Null) {System. out. println (cl); cl = cl. getParent ();}/** the loader is different and cannot be forcibly converted ** // TestClass tc = (TestClass) clazz. newInstance (); // System. out. println (tc. i);/** get the value of class through reflection **/Object obj = clazz. newInstance (); System. out. println (clazz. getField ("I "). getInt (obj); System. out. println (clazz. getField ("j "). getLong (obj ));}}