JavaVM, reflection and dynamic agent
Java program work mechanism: Java object exists with separate Class files, the Java virtual machine loads and executes its virtual machine instructions.
Java virtual machine Find these Java objects:
The Java virtual machine finds the Java object according to the Class Path, and the Class Path of the virtual machine is divided into three layers:
Bootstrap: sun.boot.class.path
Extension: java.ext.dirs
Application: java.class.path
Three Class Path have corresponding ClassLoader. Father and child relationship
The new instruction is called in the program, or when the ClassLoader.Load method is called. The order is as follows:
1. First check if there is a corresponding Class Cache in the Application's ClassLoad, if it returns, and allocates memory according to Class. If not, take a step.
2. First check if there is a corresponding Class Cache in the extension, if it is returned, and allocate memory according to Class. If not, take a step.
3. First check if there is a corresponding Class Cache in the BootStrap ClassLoad, if it returns, and allocates memory according to Class. If not, take a step.
4. ClassLoad of Bootstrap Attempts to load the Class in its Class Path, if there is, put the class into the cache and return. If not, take a step.
5. ClassLoader of Extension attempts to load the Class in its Class Path, if there is, put the Class in cache and return. If not, take a step.
6. ClassLoader at Application Attempts to load the Class in its Class Path, if there is, put the class into the cache and return. If not, throw the exception of ClassNotFound.
Java virtual machine loads these Java objects:
Each Java virtual machine generates a unique Class HEAP when it starts, and all Class Instance is allocated therein. The information for each class instance is divided into two parts, the fields domain, and the Methods domain. Each class instance has Fields, but different instances of the same class share Methods
reflection
JVM for reflection
Simple example code:
Import java.lang.reflect.invocationhandler; import java.lang.reflect.method; import java.lang.reflect.InvocationTargeTexception; import java.ioException;
Public class
Main
{Public static void main (string [] args) {Tempimpl T1 = New Tempimpl ("temp1"); try {method t1talk = t1.getClass (). GetMethod ("Talk", new class [0]); t1talk.invoke (t1, null);} catch (NoSuchMethodException e) {e.printStackTrace (); // To change body of catch statement use File | Settings | File Templates} catch (IllegalAccessException e) {e.printStackTrace ();. // To change body of catch statement use File | Settings | File Templates} catch (InvocationTargetException e) {e.printStackTrace ();.. // To change body of catch statement use File | Settings | File Templates} try {System.in. {E.PrintStackTRACE (); // to change body of catch statement USE File | Settings | file templates.}}} complex example code:
Import java.lang.reflect.invocationhandler; import java.lang.reflect.method; import java.lang.reflect.InvocationTargeTexception; import java.ioException;
Public class
Main
{Public static void main (string [] args) {Tempimpl T1 = New Tempimpl ("temp1"); Tempimpl T2 = New TempimPL ("Temp2"); Temp2 Temp2 = New Temp2 (); try {method t1talk = T1.GetClass () .getMethod ("Talk", New class [0]); method t2talk = t2.getClass (). getMethod ("talk", new class [0]); t1talk.invoke (t2, null); t2talk.invoke (T1, NULL); IF (T1Talk.Equals (t2talk)) {system.out.println ("equals");} else {system.out.println ("not equals");} if (t1talk == t2talk) {System.out.println ("Ref Equals");} else {system.out.println ("ref not equals");} T2talk.invoke (Temp2, null);} catch (Nosuchmethodexcection E) {E.PrintStackTrace ); // to change file | settings | file templates.} Catch (IllegaCCssexcept ion e) {e.printStackTrace (); // To change body of catch statement use File | Settings | File Templates.} catch (InvocationTargetException e) {e.printStackTrace (); // To change body of catch statement use File | Settings | file templates.};} Catch (ooException e) {E.PrintStackTrace (); // to change body of catch statement USE File | Settings | file templates.}}}}
Analysis: Java virtual machine uses each Method to a execution unit. This execution unit has two signatures: class signature and attribute signature (public, static, etc.). The first step of the reflection verifies the legality of the signature. After the verification, the instructions in the method are executed sequentially, and when the field of the class instance is needed, the virtual machine is injected. Dynamic agent
SUN's description of dynamic agents:
A simple example code:
Dynamic agent internal implementation - code generation:
To study the JDK source code, found that the GenerateProxyClass (Interfacs) method of the Sun.Misc.ProxyGenerator class is called in the SUN implementation of Proxy, and its return value is the same as the memory type of the CLASS file. So the following trial:
public class ProxyClassFile {public static void main (String [] args) {String proxyName = "TempProxy"; TempImpl t = new TempImpl ( "proxy"); Class [] interfaces = t.getClass () getInterfaces ();. byte [ ] proxyClassFile = ProxyGenerator.generateProxyClass (proxyName, interfaces); File f = new File ( "classes / TempProxy.class"); try {FileOutputStream fos = new FileOutputStream (f); fos.write (proxyClassFile); fos.flush () Fos.close ();} catch (filenotfoundexception e) {E.PrintStackTrace (); // to change body of catch statement use file | settings | file templates.} Catch (ooException e) {E.PrintStackTrace (); / / TO CHANGE BODY OF CATCH Statement Uses | file templates.}}}
Run this class, go to the Class folder, use the anti-compilation technology to find the original code production technology:
Public interface temp {
Public void talk ();
Public void run ();
}
Import java.lang.reflect. *;
Public Final Class Tempproxy Extends Proxy
Implements temp {
Private static method m4;
Private static method m2;
Private static method m0;
Private static method m3;
Private static method m1;
Public Tempproxy (InvocationHandler InvocationHandler) {Super (InvocationHandler);
}
Public final void run () {
Try {
H.invoke (this, m4, null);
Return;
}
Catch (error _ex) {}
Catch (throwable throwable) {
Throw new undeclaredthrowableException (throwable);
}
}
Public final string toString () {
Try {
Return (String) H.invoke (this, M2, NULL);
}
Catch (error _ex) {}
Catch (throwable throwable) {
Throw new undeclaredthrowableException (throwable);
}
""; "
}
Public final int.comode () {
Try {
Return ((Integer) H.INVOKE (this, M0, NULL). INTVALUE ();
}
Catch (error _ex) {}
Catch (throwable throwable) {
Throw new undeclaredthrowableException (throwable);
}
Return 123;
}
Public final void talk () {
Try {
H.invoke (this, m3, null);
Return;
}
Catch (error _ex) {}
Catch (throwable throwable) {
Throw new undeclaredthrowableException (throwable);
}
}
Public Final Boolean Equals (Object Obj) {
Try {
Return ((Boolean) H.invoke (this, m1, new object [] {
Obj
})). BooleanValue ();
}
Catch (error _ex) {}
Catch (throwable throwable) {
Throw new undeclaredthrowableException (throwable);
}
Return False;
}
STATIC {
Try {
M4 = Class.Forname ("temp"). getMethod ("run", new class [0]);
M2 = Class.Forname ("java.lang.object"). getMethod ("TOSTRING", New class [0]);
M0 = Class.Forname ("java.lang.object"). getMethod ("Hashcode", New Class [0]);
M3 = Class.Forname ("Temp"). getMethod ("Talk", New Class [0]);
M1 = Class.Forname ("java.lang.object"). getMethod ("equals", new class [] {
Class.Forname ("java.lang.Object")
});
}
Catch (Nosuchmethodexception NosuchmethmedException) {
Throw new nosuchmethoderror (nosuchmethodexception.getMessage ());}
Catch (classnotfoundexception classnotfoundexception) {
Throw new noclassdeffounderror (ClassNotFoundException.getMessage ());
}
}
}