Java Category Loader
1 Java dynamic characteristics
There are two kinds of dynamic characteristics of Java, one is implicit; the other is displayed. Implicit method is when the model is used to use the New this Java keyword, which allows the category loader to load the category you need by demand, which uses implicitly (Implicit) methods. Explicit method, divided into two ways, one is the other () method in java.lang.class, another
It is a loadClass () method in java.lang.classloader. You can use one of the methods anywhere.
2 implicit dynamic characteristics
When executing a Java file, only a separate variable declaration is not loaded into the corresponding class, only if you generate an instance with a New
As shown in example:
Public class
Main
Public static void main (string args [])
{
A a a1 = new a ();
B B1;
}
Class A and B are the same as follows:
Public Class A
{
Public Void Print ("Using A");
}
After compiling, you can run with java -verbose: Class Main, check the output results. It can be seen that JVM loads A without loading B.
In addition, the type of load is only loaded only when the New is executed, and if the NEW statement is not executed, it is not loaded.
Such as: // class Offic
Public Class Office
{
Public static void main (string [] args)
{
Word myword = NULL;
Excel MyExcel = NULL;
IF (args [0]. Equals ("word")))
{
myword = new word ();
myword.start ();
}
IF (Args [0]. Equals ("Excel"))
{
MyExcel = new Excel ();
myexcel.start ();
}
}
}
// class Word and Excel are basically the same, as follows
Public Class Word
{
Public void start ()
{
System.out.Println ("Using Word");
}
}
At the DOS command prompt, enter Java -verbose Office Excel can see the JVM only loads the Excel class without loading the Word class.
3 Dynamic characteristics displayed
3.1 forname () method in java.lang.class
In the previous Office example, make the following modifications:
Join Assembly class
Public interface assembly
{
Public void start ();
}
Second to make Word and Excel classes
Public Class Word IMPLEments Assembly
{
Public void start ()
{
System.out.Println ("Using Word");
}
}
The third Office class is as follows
Public Class Office
{
Public static void main (string [] args) Throws Exception
{
Java.lang.class c = java.lang.class.Forname (args [0]);
Object o = c.newinstance ();
AskEMBLY A = (askEMBLY) O;
a.Start ();
}
Enter Java -verbose Office Word output in the command prompt:
Through the figure above, you can see that the interfab is usually generated by the compiler, which will generate a separate category (.class), when the category load is loaded, if this category has inherited other categories, or Other interfaces, you will first load the category file representing the interface, which will also load the category file of its parent category. If the parent category also has its parent category, it will be prioritized. In other words, the category loader will be subloaded in order to inherit the uppermost class, until all the ancestors are loaded, and they will be loaded.
Let's introduce the Forname function if you personally search the Java 2 SDK instructions for the Class of Class for Class, you can find that there are two forname () methods, one is only one parameter (it is used in front) ):
Public Static Class forname (String ClassName)
The other is three parameters:
Public Static Class Forname (String Name, Boolean Initialize, ClassLoader Loader)
These two methods are finally connected to the native method forname0 (), which is as follows:
Private Static Native Class Forname0 (String Name, Boolean Initialize, ClassLoader Loader)
THROWS CLASSNOTFOUNDEXCEPTION;
There is only one parameter () method, and finally is:
Forname0 (ClassName, True, ClassLoader.getCallerclassLoader ());
The forname () method with three parameters, and finally use:
Forname0 (Name, Initialize, Loader);
Here INITIALIZE parameters refer to whether to initialize after loading, the role of this parameter is available as follows:
The static initial block in the class is called when the class is first initialized, and only calls once. Add a static initialization block in the Word class
Public Class Word IMPLEments Assembly
{
Static
{
System.out.Println ("Word Static Initialization");
}
Public void start ()
{
System.out.Println ("Using Word");
}
}
Change class Office as follows:
Public Class Office
{
Public static void main (string [] args) Throws Exception
{
Office OFF = new office ();
System.out.println ("Category Preparation Load");
Java.lang.class c = java.lang.class.forname (args [0], true, off.getclass (); getClassLoader ());
System.out.println ("Category Preparation Substitution");
Object o = c.newinstance ();
Object O2 = c.newinstance ();
}
}
If the second parameter is True, output it under
If false, the output is output:
It can be seen that the static initialization block in the class is only executed when initialization is initialized, but it is initialized several times, it is only executed (there is a condition, that is, it is only loaded multiple times by the same category loader. This is, if it is loaded multiple times, the static initialization block is executed multiple times if it is loaded. For the third parameter, please see the next step.
3.2 Direct Use Category Loader Java.lang.classLoader
In Java, the last old ancestors of each category are Object, and there is a method called getClass () in Object, which is used to obtain a reference to the category of a particular entity. This reference is a name. Class Class (Class.class) entity, you can't generate a Class category entity because it is declared as private, and this Class category entity is in the category file (.CLASS) first load memory Established, you will have any entities of such a class in the program, and the inside of these entities will have a field recorded in the location of this Class category.
Basically, we can put each Class category entity as an agent in a category. Every time we need
Query this category of information (such as Field, Method, etc.), you can ask this entity to help us. In fact, Java's Reflection mechanism uses the Class Category. Go deep into the original code of the Class Category, we can find that most of the methods in the definition of the Class category are native method (Native Method).
In Java, each category is loaded by a category loader (entity), so in the entity of the Class category, there will be an entity that loads its ClassLoader loaded into its column (Note: If the field is NULL, it does not mean that it is not loaded by the category loader, but represents this category by the boots loader (Bootstrap Loader, also known as rootloader), but because of this The entry is not written in Java, which is written with C , so there is no entity on the logically).
There are multiple ClassLoad entities in the system, and a class bearer is not limited to only load a category, and the category loader can load multiple categories. Therefore, as long as the reference of the Class category entity can be used, it can be used to obtain a reference to the type loader loaded into this category. The getClassLoader () method will finally call the native method getClassLoader0 (), which is as follows: Private Native ClassLoader getClassLoader0 ();
Finally, I get the entity of the ClassLoader, we can call it with its loadclass () method to help us load our category, so the above office class can make the following modifications:
Public Class Office
{
Public static void main (string [] args) Throws Exception
{
Office OFF = new office ();
System.out.println ("Category Preparation Load");
ClassLoader Loader = Off.getClass (). GetClassLoader ();
Java.lang.class c = loadinger.loadclass (args [0]);
System.out.println ("Category Preparation Substitution");
Object o = c.newinstance (); object o2 = c.newinstance ();
}
}
Its output result is the same as the second parameter of the ForName method. It can be seen that the load is loaded only when loading and is not initialized.
Get ClassLoader can also use the following methods:
Public Class Office
{
Public static void main (string [] args) Throws Exception
{
Java.lang.class cb = office.class;
System.out.println ("Category Preparation Load");
ClassLoader Loader = CB.GetClassLoader ();
Java.lang.class c = loadinger.loadclass (args [0]);
System.out.println ("Category Preparation Substitution");
Object o = c.newinstance ();
Object O2 = c.newinstance ();
}
}
Before we talk about the use of classes to load the category, we use the existing category loaders to help us
Enter the category we specified. So, can we generate a category loader to help us load the category? The answer is certain.
You can do it with the Java.Net.urclassLoader category provided by Java itself.
Public Class Office
{
Public static void main (string [] args) Throws Exception
{
URL U = New URL ("File: / D: / MyApp / ClassLoad /");
UrlclassLoader UCL = New UrlclassLoader (new url [] {u});
Java.lang.class c = ucl.loadclass (args [0]);
Assembly asm = (askMBLY) c.newinstance ();
ask.Start ();
}
}
In this example, we generate the entity of Java.Net.urlclassLoader to help us load the categories we need. But before loading, we must tell URLClassLoader which place to find the category we specified, so we must give it an array of URL categories, representing all where we want it to go to search. The URL can point to any location on the Internet, or point to the archive system in our computer (including JAR file). In the above example, we want UrlclassLoader to D: / my / lib / this directory to find the category we need, so the specified URL is "File: / D: / my / lib /". In fact, if we requested the location of the primary category (with the category of public static void main (string args []) method), we can write only "file: lib /" in the URL, representative relative to the current the catalog.
Let's take a look at the three categories of the system to provide us:
Java.exe is to use several basic principles to find Java Runtime Environment (JRE), then transfer the class file directly to JRE execution, Java.exe is ready to return. The category loader is also an important member of JRE, so the final class loader automatically loads the base category library from the /lib/rt.jar under the JRE directory.
When we entered Java Xxx.class in the command, Java.exe found JRE (Java Runtime Environment) based on the logic we mentioned before, then found JVM.dll in JRE (true Java virtual machine) ), Finally loaded into this dynamic coupling library, start Java virtual machines. When the virtual machine starts, you will do some initialization movements, computers to the system parameters. Once the initialization action is completed, the first category loader is generated, that is, the so-called Bootstrap Loader, Bootstrap Loader is written by C (so we said, in Java's point of view, there is no existence The category entity of Bootstrap Loader, so when you try to print its content in the Java program, the output we will see is null. In the initial work of this Bootstrap Loader, in addition to the basic initialization action. The most important thing is to load ExtClassLoader in Launcher.java defined under Sun.MISC namespace (because it is inner class, so it will become launcher $ extclassloader.class, and set its Parent as NULL, representing it The parent is bootstraploader. Then Bootstrap Loader then requires the AppClassLoad in Launcher.java defined under Sun.misc namespace (because it is inner class, so it will become launcher $ appclassloader.class, and set its Parent to previously generated EXTCLASSLOADER) entity.
Here, please note that Launcher $ ExtClassLoader.class may be loaded by BootStrap Loader, so Parent and which category load load is not related.
The hierarchical relationship between the three loaders can be observed by running the following example:
Public Class Test
{
Public static void main (string [] args)
{
ClassLoader CL1 = Test.class.getClassLoader ();
System.out.println (CL1);
ClassLoader CL2 = CL1.GETPARENT ();
System.out.println (CL2);
ClassLoader Cl3 = cl2.getParent ();
System.out.println (CL3);
}
}
operation result:
Sun.misc.launcher $AppClassLoader@1a0c10f
Sun.misc.launcher $EXTClassLoader@e2eec8
NULL
//
If in the above process, if you use the program code:
CL1.GetClass.getClassLoader () and cl2.getclass.getClassLoader (), you will find printed NULL,
This represents them all loaded by Bootstrap Loader. This is also emphasized again that the category loader is loaded (this sentence is a bit
Surprise, the category loader is also loaded by the category load, because in addition to bootstrap loadinger, the rest of the class
The inner is written by Java), and it is nothing to do with its Parent, and the existence of Parent is just for some special purposes, which will be explained later.
To be noted here, AppClassLoader and ExtClassLoader are subcategories for UrlclassLoader.
Since they are subcategories of UrlclassLoader, they should have a URL as a reference for search class, by the original code
We can learn that the URL referenced by AppClassLoader is determined by the string from the system parameter java.class.path,
Java.class.path is made up of our -cp or -classpath or claspath environment when performing Java.exe
Number decision.
Test as follows:
Public Class Aploader
{
Public static void main (string [] args)
{
String s = system.getProperty ("java.class.path");
System.out.println (s);
}
}
/
D: / myapp / classload> java coploader
D: /webapps/Axis/web-inf/lib/axis.jar; D: /myjava/tomcat5.0/weba
PPS / AXIS / Web-INF / LIB / Commons-Logging.jar; D: /myjava/tomcat5.0/webapps/axis/web-in
F / lib / commit-discovery.jar; c: /oacle/ora81/jdbc/lib/classes12.zip; d: / myjava / jdb
CFORSQLSERVER / lib / mssqlserver.jar; d: /myjava/jdbcforsqlserver/lib/msbase.jar; D: / M
Yjava / jdbcforsqlserver / lib / msutil.jar; D: /myjava/tomcat5.0/common/lib/servlet-api
.jar; d: /myjava/j2sdk1.4.2_04/jre/lib/rt.jar; c: /sun/appserver/lib/j2ee.jar; D: / myj
AVA / J2SDK1.4.2_04 / lib / jaxp.jar; d: /myjava/j2sdk1.4.2_04/lib/sax.jar;
D: / myapp / classload> java -classpath.; D: / myapp coploader
.; D: / myApp
/
From this output result, we can see that in the preset, the search path of AppClassLoader is "." (Currently
Record), if you use the -classpath option (equivalent to -cp equivalent), you can change the APPClassLoad's search path, if not
Specify the -classpath option, you will search the environment variable ClassPath. If there is a ClassPath environment setting and
-classpath option, based on the content of the -classpath option, the ClassPath environment settings and the -classpath option
The content does not have an effect.
As for ExtClassLoader, there is also the same case, but its search path is the reference system parameter java.ext.dirs.
The content of the system parameter java.ext.dirs will point to the / lib / ext sub-directory under the location selected by Java.exe. Java.exe uses JRE, which is specified in the system variable path, can modify the search path of EXTCLASSLOADER by modifying Path, or change as the following command parameters, java -djava.ext.dirs = C: / Winnt / Apploader //// Note that there is no space on both sides. -D cannot be separated from Java.
D: / myapp / classload> Java ExtLoader
D: /myjava/j2sdk1.4.2_04/jre/lib/ext
D: / myapp / classload> java -djava.ext.dirs = C: / Winnt / EXTLOADER
C: / WinNT /
The last category loader is Bootstrap Loader, we can learn Bootstrap Loader to search for the path of category by system parameters sun.boot.class.path. The modification of this path is the same as the EXTCLASSLOADER. But there is no way to change the search path of Bootstrap after modification.
When the argument is columnized, use the -classpath / -cp / environment variable classpath to change AppClassLoader
Search path, or use -djava.ext.dirs to change the ExtClassLoad's search directory, both meaningful.
However, the search path of Bootstrap Loader is invalid with -dsun.boot.class.path. This is because
AppClassLoader and EXTCLASSLOADER are established for the content of these two system parameters, when you are listed in the command
After changing these two system parameters, AppClassLoader and ExtClassLoader will refer to these two systems when establishing an entity.
The parameters thus changed their path to the class files; and the system parameter sun.boot.class.path is the preset
Bootstrap Loader's search path is the same, even if you change the system, it is completely unrelated to Bootstrap Loader.
Changing the JRE used by Java.exe will change the search path of the Bootstrap Loader.
The search path of Bootstrap Loader is generally as follows:
///
D: /myjava/j2sdk1.4.2_04/jre/lib/rt.jar; d: /myjava/j2sdk1.4.2_04/jRE/LIB/i18n.jar;
D: /myjava/j2sdk1.4.2_04/jre/lib/sunrsasign.jar; d: /myjava/j2sdk1.4.2_04/jre/lib/j
SSE.jar; D: /myjava/j2sdk1.4.2_04/jre/lib/jce.jar; d: /myjava/j2sdk1.4.2_04/jre/lib/
Charsets.jar; d: /myjava/j2sdk1.4.2_04/jre/classes
///
More importantly, AppClassLoader and ExtClassLoader will only have one in the entire virtual machine.
It is standing, the search path in the inside is no longer changed, that is, even if we use System.SetProperty () in the program.
To change the content of the system parameters, still unavoidable path for AppClassLoader and ExtClassLoader. Therefore,
The setting of the dynamic changes to the search path is impossible. If you have a special needs, some categories of the path are not
At the beginning, you can decide, in addition to generating a new category loader, there is no other way, there is no other way, in addition to the new category loader.
Below we will look at the so-called delegation model of the delegation model of the loader. In a simple words, "The Category loader has the need to load classes, please ask the Parent using its search path to help load, if PARENT can't find it, then you can search by yourself in your own search path.
Let's take a look at a small example:
Public Class Test
{
Public static void main (string [] args)
{
System.out.println (TEST.CLASS.GETCLASSLOADER ());
Testlib TL = New TestLib ();
TL.Start ();
}
}
Public Class Testlib
{
Public void start ()
{
System.out.println (this.getClass (). GetClassLoader ());
}
}
If these two classes are placed on the current directory of the DOS command prompt, the output results are as follows:
//
Sun.misc.launcher $AppClassLoader@1a0c10f
Sun.misc.launcher $AppClassLoader@1a0c10f
//
If these two categories are placed under the
/
Sun.misc.launcher $EXTClassLoader@e2eec8
Sun.misc.launcher $EXTClassLoader@e2eec8
Finally, if you put these two classes under the directory> / classes of / NULL NULL If you delete the testlib under the "Directory> / Classes under", the output is output. // NULL Exception in thread "main" java.lang.noclassdefounderror: testlib At test.main (Test.java: 7) // This is because Test's ClassLoader is Bootstrap Loader, so TestLib's also default is Bootstrap Loader. Bootstrap Loader Searching Testlib is deleted, Bootstrap Loader has no Parent, so the prompt cannot be found. Other situations can add or delete files one by one, and then perform Java Test to test and check the output results. AppClassLoader and Bootstrap Loader will search for the location (or JAR file) specified, if you can't find it, AppClassLoader and Bootstrap Loader do not deliver other paths in these locations or other JARs that are not specified. files. Confused EXTCLASSLOADER, the system parameters referred to are java.ext.dirs, meaning that he will search all JAR files under the bottom and the ClassS directory as its search path.