The loading process of the class
Java classes from load to unload are roughly as follows
Some of the content of the work:
First, load
Gets a binary stream using the full name of the class, generating a class object in memory.
Second, verification
Ensure that the contents of the class file do not compromise the security of the virtual machine itself.
Third, prepare
Assigns an initial value to a class variable. Fixed variables with final decoration are assigned a specific value, and the other assigns a value of 0.
Iv. Analysis
A virtual machine replaces a symbolic reference in a constant pool with a direct reference procedure
Class Loader
(1) Bootstrap ClassLoader
This loader is implemented by C + + and is part of the virtual machine, which mainly loads core jars such as Rt.jar.
(2) Extclassloader
Responsible for loading the jar packages in Jre/lib/ext
(3) Appclassloader
The class that is responsible for loading the user class path
Introduction to Parental delegation model
When a ClassLoader instance needs to load a class, it attempts to search for a class by itself, delegating the task to its parent classloader, which is checked from top to bottom, first by the topmost class loader bootstrap classloader trying to load, If not loaded, the task is forwarded to the extension ClassLoader attempt to load, if not loaded, then to the app ClassLoader to load, if it is not loaded, then return to the initiator of the delegate, It loads the class into a URL such as a specified file system or network.
Implement a ClassLoader yourself
Public class myclassloader extends ClassLoader { @Override protectedClass<?>Findclass(String name)throwsclassnotfoundexception {Class Clazz =NULL;//this.findloadedclass (name);//parent class loaded //if (clazz = = null) {//check if the class has been loaded byte[] Classdata = Getclassdata (name);The byte-code array of the class file is obtained based on the binary name of the if(Classdata = =NULL) {Throw NewClassNotFoundException (); } clazz = defineclass (name, Classdata,0, classdata.length);//Convert a class byte array into an instance of class //} returnClazz; }Private byte[]Getclassdata(String className) {Bytearrayoutputstream stream =NewBytearrayoutputstream ();byte[] buffer =New byte[1024x768];intLen =0; String Path ="C:\\users\\administrator\\desktop"+ File.separator; Path + = Classname.replace ('. ', File.separatorchar) +". Class";Try{InputStream is =NewFileInputStream (path); while(len = is.read (buffer))! =-1) {Stream.Write (buffer,0, Len); }returnStream.tobytearray (); }Catch(IOException e) {E.printstacktrace (); }return NULL; } }
publicclass Test { publicstaticvoidmain(String[] args) throws ClassNotFoundException { new MyClassLoader(); "MapTest"; Class<?> clazz = classLoader.loadClass(path); System.out.println(clazz.getClassLoader()); System.out.println(clazz.getName()); }}
Output:
[Email protected]
Maptest
Some questions why use this loading model
Because this avoids repeated loading, there is no need for the child classloader to load again when the parent has loaded the class. Considering the security factors, let's imagine that if we don't use this delegate pattern, we can use a custom string at any time to dynamically replace the type defined in the Java Core API, so there's a very big security risk, and the way that parents delegate, you can avoid this situation, Because the string has been loaded by the Boot class loader (BOOTSTRCP ClassLoader) at startup, the user-defined ClassLoader can never load a string that he writes, Unless you change the default algorithm for the ClassLoader search class in the JDK.
Class.forName and Classloader.loadclass () difference?
Class loading is divided into three stages, loading,linking and initializing,
Class.forName (ClassName) is actually called Class.forName (ClassName, True, This.getclass (). getClassLoader ()). Note that the second parameter is whether the class must be initialized after it is loading. Classloader.loadclass (className) actually calls Classloader.loadclass (name, false), and the second parameter indicates whether the class is being link. The difference is out. Class.forName (ClassName) loaded class has been initialized, and Classloader.loadclass (ClassName) loaded class has not been link. Forname supports array types, LoadClass does not support arrays in general, both of these methods have the same effect of loading class. However, if the program depends on whether the class is initialized, you must use Class.forName (name).
Deep understanding of Java class loading