In a summary of today's reflection, in several parts of the javase application, I think reflection is a very important element, because we are inseparable from the subsequent learning framework and the understanding of programming ideas. The content is not many but needs to be understood.
1. Why should there be reflection?
In some cases, we need to know at runtime to use a class that is completely unknown at compile time, create its object, and invoke its methods and properties.
2. Reflections:
is considered the key to a dynamic language, allowing the program to obtain internal information about any class with the reflection API during execution, and directly manipulate the internal properties and methods of any object.
3. Class loading process:
When a program actively uses a class, if the class has not yet been loaded into memory, the system initializes the class with the following three steps.
Loading of the ① class:
Read the. class file into memory and create a Java.lang.Class object for it. There is a class loader to complete
Connection to the ② class:
Merges the binary data of the class into the JRE.
Initialization of the ③ class:
The JVM is responsible for initializing the class.
Extended:
class-Loaded features:
A class is only loaded once in the virtual machine life cycle
Load principle: Lazy loading, can be loaded less load, because the virtual machine space is limited
class loading time:
1) When you create an object for the first time
2) When a static method is called to load a class, the class is loaded when the static property is accessed
3) loading subclasses must first load the parent class
4) Create object reference does not load class
5) When a subclass calls a static method of a parent class:
① when a subclass does not overwrite a static method of a parent class, only the parent class is loaded and the subclass is not loaded
② when a child class overrides a static method of a parent class, the parent class is loaded, and the subclass is loaded
6) access to static constants, if the compiler can directly calculate the value of the constant, it will not load the class, is responsible for loading the class.
4. Get an instance of the class object:
①
Class clazz = Person.class();
Ii
new Person();Class clazz = p.getClass();
③
"com.qh.review.Person";Class clazz = Class.forName(className);
④
"com.qh.review.Person";ClassLoader cl = Person.class.getClassLoader();class clazz = cl.loadClass(className );
5. Class Loader
① getting the System class loader
ClassLoader cl = ClassLoader.getSystemClassLoader();System.out.println(cl);
Note: Responsible for loading all the jar packages under Classpath
② Get Extension class loader
ClassLoader cl2 = cl.getParent();System.out.println(cl2);
Note: Responsible for loading all the jar packages under Jre/lib/ext
ClassLoader cl3 = cl2.getParent();System.out.println(cl3);
Note: Responsible for loading the core class library, not directly get
Gets the class to which the current class is loaded:
ClassLoader cl = Person.class.ClassLoader();System.out.println(cl);
6. Getting an object instance by reflection
Person person = Person.class().newInstance();
Note: this newinstance () actually calls the constructor of the class. You can test by declaring a constructor with a parameter.
7. Operation Properties, here's the code, I put the content of my review today, we do not want to see can jump down. Want to see can make a reference.
//Operation Properties @Test Public void test4() {//Get the class object for the specific classes firstClass<?> Clazz =NULL;Try{clazz = Class.forName ("Com.qh.review2.Person"); }Catch(ClassNotFoundException e) {E.printstacktrace (); }//through Clazz to get class properties---->public 1,protected 4, private 2, default 0field[] fields = Clazz.getfields ();//Only properties that access control modifiers are public can be obtained. Access control modifier 1 is public for(Field field:fields) {System.out.println (Field.getname ());//PhoneSystem.out.println (Field.gettype ());//1System.out.println (Field.getmodifiers ());//Class java.lang.String} System.out.println ("---------------------------------------------"); field[] Fields2 = Clazz.getdeclaredfields (); for(Field field:fields2) {System.out.println (Field.getname ()); System.out.println (Field.getmodifiers ()); System.out.println (Field.gettype ()); System.out.println ("************"); }//Manipulate the properties of an object: After a class is determined, it cannot modify its modifier, data type, name. When working with private properties, you need to modify the access permissions. Field name =NULL; Person person =NULL;Try{person = (person) clazz.newinstance (); Name = Clazz.getdeclaredfield ("Name"); Name.setaccessible (true); Name.set (Person,"Zhang San"); }Catch(Instantiationexception | illegalaccessexception | nosuchfieldexception | SecurityException e) {e.printstacktrace (); } System.out.println (person); }
8. How to Operate
@Test Public void Test5() {//Get all methods---the modifier of the > method returns an indeterminate number.? Method[] methods = Clazz.getdeclaredmethods (); for(inti =0; i < methods.length; i++) {System.out.println ("Access control modifier:"+ methods[i].getmodifiers ()); System.out.println ("return value type:"+ Methods[i].getreturntype ()); System.out.println ("Method Name:"+ Methods[i].getname ()); class<?>[] ParameterType = Methods[i].getparametertypes (); for(Object Paramobject:parametertype) {System.out.println ("parameter type:"+ Paramobject); } class<?>[] Exceptiontypes = Methods[i].getexceptiontypes (); for(Object etype:exceptiontypes) {System.out.println ("Exception type:"+ EType); } type[] Grnerictypes = Methods[i].getgenericparametertypes (); for(Type type:grnerictypes) {System.out.println ("generic type:"+ type); } System.out.println ("------------------------------------------"); }//action method:---> method can only be called. System.out.println (" How to");Try{Person person = clazz.newinstance (); Method getName = Clazz.getdeclaredmethod ("GetName"); System.out.println (Getname.invoke (person)); }Catch(Instantiationexception | illegalaccessexception | nosuchmethodexception | SecurityException | IllegalArgumentException | InvocationTargetException e) {e.printstacktrace (); } }
I refer to the object of the acquisition class outside, or I have to write it every time.
Important: Be sure to note the invocation of the method here. The following dynamic proxies and AOP are used.
8. Get the parent generic type, it's pretty important to feel this. I wrote it in JDBC a while ago. I'll just write it.
Class clazz = Person.class();Type type = clazz.getGenericSuperClass();ParameterizedType types = (ParameterizedType)type;for(Type t : types){ System.out.println(t);}
These things must be memorized, to a notepad can be written out, and do not make mistakes. That's what I'm asking of me.
9. There are some types, I will not say here, you can see the API documentation about reflection
Next write three applications:
Before writing a dynamic agent, let's review how static proxies are written.
1. Static Proxy
The proxy class and the proxy class implement the same interface, and the method in the proxy class is called through the proxy class object, but the method is actually called by the proxy class object to accomplish the corresponding function.
Sweat, unexpectedly did not have my morning summary of good, come to see.
An interface, a proxy class, a proxy class, a proxy class, and a proxy class can all implement methods in the interface.
the proxy class executes the method in the proxy class through the proxy class.
Interface factory{voidProduce ();}//By proxy classClass Nikefactory implements factory{ Public void Produce() {System.out.println ("Production of Nike clothes. "); }}//proxy classClass Nikeproxy implements factory{nikefactory NF =NULL;//The proxy class object that actually calls the method Public Nikeproxy(Nikefactory NF) { This. NF = NF;//Initialize this object} Public void Produce() {nf.produce ();//Actually is the agent class object to produce the clothes}} Public class Proxy{ Public void Main(string[] args) {Nikefactory NF =NewNikefactory (); Nikeproxy NP =NewNikeproxy (NF); Np.produce ();//production of Nike clothes. }}
Do you understand me? In fact, dynamic proxies and AOP are logically the same as this. Only static proxies can only be targeted to specific objects.
2. Dynamic Agent:
Interface factory{//or just the same as voidProduce ();} Class Nikefactory implements factory{//or just the same as Public void Produce() {System.out.println ("Production of Nike clothes. "); }}//See proxy classClass Myinvocationhandler implements invocationhandler{Object obj =NULL;//or This proxy class object //Need a proxy class object, of course, through the reflection of the way to get it! PublicObjectGetProxy(Object obj) { This. obj = obj;//Initialize a bit returnProxy.newproxyinstance (Obj.getclass (). getClassLoader (), Obj.getclass (). Getinterfaces (), This); }//method of implementation not remember, stick it. The //proxy class is converted to a call to this method when it executes the proxy class method. @Override PublicObjectInvoke(Object Proxy, Method method, object[] args)throwsThrowable {//Do you remember the precautions I have taken above through the reflection operation method? Let's look back. returnMethod.invoke (obj, args);///ditto, or you can't understand it here. }} Public class testproxy{ Public void Main(string[] args) {Nikefactory NF =NewNikefactory (); Myinvocationhandler MiH =NewMyinvocationhandler (); Object obj = Mih.getproxy (NF);//Returns the proxy class objectFactory f = (Factory) obj;//Implements the factory interfaceF.produce ();//Is it in the production of Nike clothes? }}
3.AOP (Aspect oriented programming) programming for facets. So far, this is the first example of aspect-oriented programming that I've seen, probably just mastering its form and not understanding its connotation. will increase their understanding as they learn from the future.
Take a look at the picture:
In fact, the specific content and dynamic agents are no different. The code will not be written. Let's stick it out for everyone.
Interface Human {voidWalk ();voidFly ();} Class Superman implements Human {@Override Public void Walk() {System.out.println ("Walking, walking, walking, walking."); }@Override Public void Fly() {System.out.println ("I belive I Can Fly"); }}class Humanutil { Public void method1() {System.out.println ("Method 1!!!!"); } Public void method2() {System.out.println ("Method 2!!!!"); }}//Get proxy objectClass Maninvocationhandler implements Invocationhandler {Object obj; PublicObjectGetProxy(Object obj) { This. obj = obj;returnProxy.newproxyinstance (Obj.getclass (). getClassLoader (), obj. GetClass (). Getinterfaces (), This); }@Override PublicObjectInvoke(Object Proxy, Method method, object[] args)throwsthrowable {Humanutil H1 =NewHumanutil (); H1.method1 (); Object returnval = Method.invoke (obj, args); H1.METHOD2 ();returnReturnVal; }} Public class testaop { Public Static void Main(string[] args) {Superman SM =NewSuperman (); Maninvocationhandler MiH =NewManinvocationhandler (); Object obj = mih.getproxy (SM); Human proxy = (Human) obj; Proxy.walk (); System.out.println (); Proxy.fly (); }}
- Multiple code snippets have the same duplicated code, we extract the duplicated code,
- Encapsulation method, but this method is fixed, increasing the coupling with the multi-segment code.
- Our ideal way is to encapsulate the method is not fixed, dynamic,
- This greatly reduces the coupling between the code, the dependencies between the code.
This is the aspect-oriented programming I understand now.
Well, it's here today.
Javase: Reflection Summary (Reflection)