Reflection and dynamic proxies are common and important in a variety of commonly used frameworks. This article summarizes the content of this section in a basic way.
The first thing you need to know is the type information, and the relationship and difference between Rtti and reflection.
In Java, you use class objects to represent objects of all classes. Use class objects to get member variables, constructors, and methods in a class, which we call type information. The implication of Rtti is that the type of an object is recognized at run time, but there is a premise that the type must be known at compile time in order to recognize it with RTTI and use that information to do something useful. But how can you use this class if, at compile time, the program has no way of knowing what class this object belongs to? The answer is that we can let the JVM load the class object at run time. Since there is no compile-time check, the JVM will simply check the object to see which particular class it belongs to and then load the class object. So the difference between Rtti and reflection is that the former is to open and check the. class file at compile time, and the runtime loads the class object for the required classes, while the latter is to open and inspect the. class file at run time and load the class object of the required classes.
As an example:
class test{ publicstaticvoid main (string[] args) { new Dev (); }}
When compiling it, if the package does not have the Dev class, then the compilation will error:
C:\users\brucechan\desktop\test>javac Test.javaTest.java:3: Error: Symbol new not found Dev (); ^ symbol: class Dev Location: Class Test1 Error
But if we modify it to reflect the way:
class test{ publicstaticvoid main (string[] args) { try { class.forname ("Dev"); } Catch (ClassNotFoundException e) { System.out.print (e.tostring ()); }}}
Compiling it will find that the compilation will run smoothly even without the Dev class, because it will be loaded at runtime when it is used with the Dev class.
---------------------------------------------------------------------------------->
Next, here in the form of code in the reflection technology, commonly used routines. In reflection, there are three ways to get a class object of type:
Try { = Class.forName ("Com.changjiang.test.RFP01.testReflect.MyClass"catch ( ClassNotFoundException e) { e.printstacktrace ();}
New== MyClass. class;
Through the class object, you can get its properties, methods, constructors, just say its method call, first give the original class:
PackageCom.changjiang.test.RFP01.testReflect;Importjava.util.Date; Public classMyClass {Private intmyInt; PrivateString myString; PublicMyClass () {} PublicMyClass (inta) { This. myInt =A; System.out.println (a); } Public voidmethod2void () {} Public intMethod2int () {System.out.println ("Method2int has run"); return0; } PublicString method2string () {return""; } PublicObject Method2object () {return NewDate (); } Public voidMethod3param (intA, String b) {System.out.println ("Method3param have run with param-a:" + A + "and param-b:" +b); }}
Give a few more ways to call and output:
Packagecom.changjiang.test.RFP01;ImportJava.lang.reflect.Constructor;ImportJava.lang.reflect.Method;ImportCom.changjiang.test.RFP01.testReflect.MyClass; Public classMain { Public Static voidMain (string[] args) {MyClass MyClass=NewMyClass (); Class CLS=Myclass.getclass (); Try{Method m= Cls.getmethod ("Method2int",Newclass[]{});//get a method of a classM.invoke (MyClass,Newobject[]{});//The essence of the method of calling this classMethod m2= Cls.getmethod ("Method3param",Newclass[]{int.class, String.class}); M2.invoke (MyClass,NewObject[]{5, "fake"});//call the method of this class, with the parameters of theConstructor<MyClass> cons = Cls.getconstructor (Newclass[]{int.class}); Cons.newinstance (47); }Catch(Exception e) {e.printstacktrace (); } method[] Ms=Cls.getmethods (); for(Method m:ms) {System.out.print (M.getname ()+ "\ T"); } }}
Output
Method2int has run
Method3param have run with Param-a:5 and Param-b:fake
47
Method2intmethod3parammethod2stringmethod2objectmethod2voidwaitwaitwaitequalstostringhashcodegetclassnotifynotifyall
---------------------------------------------------------------------------------->
OK, speaking of which, we should look at the proxy mode. Clearly, we look at the dynamic agent again. Proxy mode, simply put, is an interface, two implementations. To implement one of the things we need to do in the implementation of the second, we not only have to do things in the implementation of one, but also before and after that we can add other things we want to do. See the code for specific content.
PackageCom.changjiang.test.RFP01.testReflect; Public classSampleproxy { Public Static voidMain (string[] args) {NewBaseSample1 (). dosomething (); System.out.println ("--------------------------------"); NewProxysample (NewBaseSample1 ()). DoSomething (); }}Interfacebaseinterface{ Public voiddosomething ();}classBaseSample1Implementsbaseinterface{ Public voiddosomething () {System.out.println ("BaseSample1"); }}classProxysampleImplementsbaseinterface{Privatebaseinterface bi; Publicproxysample (baseinterface bi) { This. Bi =bi; } Public voiddosomething () {System.out.println ("Before"); Bi.dosomething (); System.out.println ("After"); }}
Here the interface is implemented by two classes, one is the native class, the other is the proxy class, and the proxy class not only implements this interface, but also needs to assign the proxy class through the constructor to its own property, and then use the method of the original class in the interface implementation method.
---------------------------------------------------------------------------------->
Next look at the dynamic agent, mainly how to implement the dynamic agent and the core class proxy with its method newproxyinstance (ClassLoader loader, class<?>[] interfaces, Inovationhandler h) The detailed meanings and functions of several parameters are analyzed. (Next article)
Java Reflection and dynamic proxy (top)