Directory
- Objective
- The traditional Rtti
- Reflection
- How reflection is implemented
- Performance of Reflection
- Reflection and Design Patterns
Objective
Not all classes can be defined at compile time, so in some cases it is necessary to discover and determine type information at runtime (e.g., build-based programming), which is Rtti (runtime type information, run-time types information).
In Java, there are two ways of Rtti, one is traditional, assuming that all types are known at compile time, and another is to use the reflection mechanism to try to determine the type information at run time.
This paper mainly discusses the Rtti of reflection mode, and suggests to understand the loading mechanism of classes before reading this article (refer to my Blog: Java series notes (1)-Java class loading and initialization).
In this article, we will work with the following Toy class toy, which defines public, private methods, variables, constructor methods, parent classes, parent interfaces, and so on:
Package myblog.rtti;/** * @project MyBlog * @create June 28, 2013 PM 4:42:46 * @version 1.0.0 * @author Zhangguang */public interface Itoy {public string Playtoy (string player) throws Exception;}
Package Myblog.rtti;public class Abstracttoy implements Itoy { @Override public string Playtoy (string player) Throws Exception { System.out.println (player + "plays abstract toy"); Return ""; }}
Package Myblog.rtti;public class Toy extends Abstracttoy {private String name; public String color; protected int size; public static final int price = 10; static {System.out.println ("Loading"); } public Toy () {//constructor method must be declared as public type, otherwise getconstructors cannot get System.out.println ("initialing"); SetName ("Mytoy"); color = "Red"; size = 5; Public Toy (string name, string color, int size) {this.setname (name); This.color = color; this.size = size; } public String GetName () {return name; } public void SetName (String name) {this.name = name; } @Override public String Playtoy (string player) throws Exception {string msg = Buildmsg (pla Yer); SYSTEM.OUT.PRINTLN (msg); return msg; }private string Buildmsg (string player) {string msg = player + "plays" + name; return msg; }}
The traditional Rtti
Strictly speaking, reflection is also a form of rtti, however, the general documentation of RTTI and reflection separate, because generally, we think rtti refers to the traditional rtti, through inheritance and polymorphism to achieve, at runtime by calling the superclass method to achieve the specific function (superclass will be automatically instantiated as subclasses , or use instance of).
There are 3 ways to achieve the traditional rtti:
- Move up or down (upcasting and downcasting), in Java, transformation down (parent class to subclass) requires forced type conversion
- Class object (using the class object, does not mean that it is reflection, if only the class object cast into the specified classes, it is still the traditional rtti)
- instanceof or Isinstance ()
The main difference between traditional Rtti and reflection is that Rtti requires. class files at compile time, and reflection is not required. Traditional rtti are implemented in the form of transformations or instance, but all need to specify the types to be transformed, such as:
public void Rtti (Object obj) { Toy Toy = Toy (obj); Toy Toy = Class.forName ("Myblog.rtti.Toy") //obj instanceof Toy}
Note that while obj is being transformed, in the compile time, you need to know the type toy to be converted, that is, the. class file that needs to be toy.
In contrast, reflection completely determines the type at run time through class, and does not require the toy. class file to be loaded in advance.
Reflection
So what exactly is reflection (Reflection)? Reflection is sometimes called introspection (introspection), in fact, reflection is an introspective way, Java does not allow the structure of the program structure or type variables to be changed at run time, but it allows the runtime to detect, load, and invoke classes that are completely unknown at compile time. You can load the class at run time, generate an instance object (instance objects), call method, or assign a value to field. This is similar to "see through" the characteristics of the class is called Reflection (Reflection), we can directly understand the reflection as: can be seen in the water reflection, this operation and direct operation source code effect is the same, but much more flexible.
About the Java Reflection API, no need to remember, can be queried in any JDK API:
Class: Http://www.ostools.net/uploads/apidocs/jdk-zh/java/lang/Class.html
Reflect Bag: http://www.ostools.net/uploads/apidocs/jdk-zh/java/lang/reflect/package-summary.html
How reflection is implemented
Package Myblog.rtti;import Java.lang.reflect.array;import Java.lang.reflect.constructor;import Java.lang.reflect.field;import Java.lang.reflect.invocationtargetexception;import Java.lang.reflect.Method; Import java.lang.reflect.modifier;/** * @project MyBlog * @create June 28, 2013 PM 3:00:33 * @version 1.0.0 * @author Zhangguang */pub Lic class Toyreflection {public static void Printinfo (String info, Object obj) {if (Obj.getclass () . IsArray ()) {System.out.println (info + ":"); int length = array.getlength (obj); System.out.println ("Array Size:" + length); for (int i = 0; i < length; i++) {System.out.print ("array[" + i + "]:" + array.get (obj , i) + ","); } if (length! = 0) System.out.println (); } System.out.println (Info + ":" + obj.tostring ()); } public static void Main (string[] args) {try {//Get class object class<?> C = class.forname ("Myblog.rtti.Toy"); Printinfo ("Acquiring Class object", C); Get Super class Class<?> superclass = C.getsuperclass (); Printinfo ("Get Super Class", superclass); Get all parent interface class<?>[] interfaces = C.getinterfaces (); Printinfo ("Get All Parent Interface", interfaces); Instantiate Toy Toy = (Toy) c.newinstance (); Printinfo ("instantiation", toy); Get the Access property to public construction method constructor<?>[] constructors = c.getconstructors (); Printinfo ("Acquiring the tectonic method", constructors); Gets the constructor method for the specified parameter constructor<?> Constructor = C.getdeclaredconstructor (string.clasS, String.class, Int.class); Printinfo ("Get Specified construction method", constructor); To obtain a method, GetMethod can only get the public method, including the parent class and interface inheritance methods method = C.getmethod ("Playtoy", String.class); Printinfo ("Access to public Methods", method); Call Method Method.invoke (toy, "Zhang San"); Get modifier, including private/public/protect,static String modifier = modifier.tostring (Method.getmodifiers ()) ; Printinfo ("Get modifier", modifier); Get parameter type class<?>[] paramtypes = Method.getparametertypes (); Printinfo ("Get parameter Type", Paramtypes); Gets the return value type class<?> returntype = Method.getreturntype (); Printinfo ("Get Return value type", ReturnType); Get exception type class<?>[] Exceptypes = method.getexcepTiontypes (); Printinfo ("Get Exception type", Exceptypes); Calling a private method, Getdeclaredmethod obtains the method of the class itself, including the Public,protect,private method method2 = C.getdeclaredmethod ("Buildmsg", String.class); Method2.setaccessible (TRUE); String result = (string) Method2.invoke (toy, "John Doe"); Printinfo ("Obtain private method", result); Get all properties field[] fields = C.getfields (); Printinfo ("Get All Attributes", fields); Gets the specified attribute of the class itself definition field field = C.getdeclaredfield ("name"); Printinfo ("Get self attribute", field); Gets the public property of the class and its parent class, defined by the parent interface Field Field2 = C.getfield ("color"); Printinfo ("Get public Attribute", field2); Get permission modifiers, including private/public/protect,static,final String fieldmodifier = ModifiEr.tostring (Field.getmodifiers ()); Printinfo ("get permission Modifier", fieldmodifier); Operation Array int[] Examplearray = {1, 2, 3, 4, 5}; Gets the array type class<?> ComponentType = Examplearray.getclass (). Getcomponenttype (); Printinfo ("Array type", Componenttype.getname ()); Get length Printinfo ("Array Length", Array.getlength (Examplearray)); Gets the specified element Printinfo ("Get array Element", Array.get (Examplearray, 2)); Modifies the specified element Array.set (Examplearray, 2, 6); Printinfo ("Modify array element", Examplearray); Gets the current class loader printinfo ("Get current ClassLoader", Toy.getclass (). getClassLoader (). GetClass (). GetName ()); } catch (ClassNotFoundException e) {e.printstacktrace (); } catch (InsTantiationexception e) {e.printstacktrace (); } catch (Illegalaccessexception e) {e.printstacktrace (); } catch (SecurityException e) {e.printstacktrace (); } catch (Nosuchmethodexception e) {e.printstacktrace (); } catch (IllegalArgumentException e) {e.printstacktrace (); } catch (InvocationTargetException e) {e.printstacktrace (); } catch (Nosuchfieldexception e) {e.printstacktrace (); } }}
With the code above, you can clearly understand how to "see yourself in the water," but there are a few things to keep in mind:
1, in the reflection mechanism of Java, Getdeclaredmethod obtains the whole method, GetMethod obtains is the public method;
2, the setaccessible of reflection mechanism may destroy encapsulation, and can access private methods and private variables arbitrarily;
3,setaccessible does not change private to public, in fact, the accessible property of the public method is also false, setaccessible just cancels the security access control check, So by setting setaccessible, you can skip access control checks and perform more efficiently. Reference: http://blog.csdn.net/devilkin64/article/details/7766792
Performance of Reflection
The reflection mechanism gives great flexibility to Java development, but the reflection mechanism itself has its drawbacks, the representative flaw is the performance of reflection, in general, the efficiency of invoking the method through reflection is at least one more than the efficiency of the direct call.
For performance issues, refer to this blog http://blog.csdn.net/l_serein/article/details/6219897
Reflection and Design Patterns
A very important function of reflection is the application in the design pattern, including the application in the Factory mode and the proxy mode. On this aspect, I will introduce in the following articles, interested friends can also refer to this article http://www.cnblogs.com/rollenholt/archive/2011/09/02/2163758.html on the dynamic proxy pattern implementation method of the article.
Resources
Java programming ideas, 14th Chapter
Java-rtti and reflection mechanism--detail: http://blog.csdn.net/dahaizisheng/article/details/1762327
Java Reflection Detailed: http://www.cnblogs.com/rollenholt/archive/2011/09/02/2163758.html
Rtti and reflection mechanism: http://blog.sina.com.cn/s/blog_5ea2d6840100v9bu.html
Rtti and reflection mechanisms in Java: http://blog.csdn.net/a81895898/article/details/8457623
Java Reflection Performance test: http://blog.csdn.net/l_serein/article/details/6219897
Java Series notes (2)-Java Rtti and reflection mechanism