Concept
The Java reflection mechanism is in the running state, for any class, can know all the properties and methods of this class, for any one object, can call any of its methods and properties; This dynamically acquired information and the ability to dynamically invoke the object's methods are called the reflection mechanisms of the Java language.
the Class class, together with the Java.lang.reflect class library, supports the concept of reflection, which contains the Field,Method , and Constructor classes ( Each class implements the Member interface). These types of objects are created by the JVM at run time to represent the corresponding members in the unknown class. This allows developers to use Constructor to create new objects, use the get () and set () methods to read and modify fields associated with the Field object, using the The Invoke () method invokes the method associated with the methods object. In addition, you can call GetFields (),getmethods (),getconstructors () , and so on, to return a convenient way of representing fields, Method and an array of objects for the constructor. In this way, the class information of an anonymous object can be fully validated at run time, and there is no need to know anything at compile time.
Class
A class is part of a program, and each class has an object of class. In other words, whenever a new class is written and compiled, it produces a class object (more appropriately, it is stored in a . class file of the same name), which contains information about the class. To generate objects of this class, the virtual machine (JVM) Running this object will use a subsystem called the ClassLoader (ClassLoader). Here are some of the most basic information for the Test class.
public class ClassInfo {/** * @description output different format class names * @param clazz */public static void Printname (Clas S<?> clazz) {System.out.println ("GetName:" + clazz.getname ()); System.out.println ("Getcanonicalname:" + clazz.getcanonicalname ()); System.out.println ("Getsimplename:" + clazz.getsimplename ()); }/** * @description the parent class and interface of the output class * @param clazz */public static void printclassintf (Class<?> cl Azz) {class<?> superclass = Clazz.getsuperclass (); Class<?>[] interfaces = Clazz.getinterfaces (); if (superclass! = null) {System.out.print (Clazz.getsimplename () + "extends" + superclass.getsimplename ()); } if (Interfaces.length > 0) {System.out.print ("implements"); for (int i = 0; i < interfaces.length-1; i++) {System.out.print (Interfaces[i].getsimplename () + ","); } System.out.println (InterfaCes[interfaces.length-1].getsimplename ()); } }}
Test class test Case: ArrayList
Import Org.junit.after;import Org.junit.before;import Org.junit.test;public class Classinfotest { private class <?> Clazz; Private String ClassName = "Java.util.ArrayList"; /** * forname () is a way to get a reference to a class object. * It is an input parameter with a string containing the text name of the target class, and returns a reference to a class object. */ @Before public Void before () { try { clazz = Class.forName (className); } catch ( ClassNotFoundException e) { e.printstacktrace (); } } @After public Void after () { clazz = null; } @Test public void Testgetname () { classinfo.printname (clazz); } @Test public void testprintclassintf () { classinfo.printclassintf (clazz); }}
Test results
GetName:java.util.ArrayListgetCanonicalName:java.util.ArrayListgetSimpleName:ArrayListArrayList extends Abstractlist implements List, Randomaccess, cloneable, Serializable
Constructor
The Constructor class is an abstraction of constructors in Java ordinary classes. An array of objects representing the constructor can be obtained through the class GetConstructors () method, through getconstructor (CLASS<?> Parametertypes) can obtain a constructor of the specified argument type. You can build an instance object by using the newinstance (Object ... initargs) method. It is important to note that the parameters of thenewinstance () method should correspond to the GetConstructor () method parameters. For example getconstructor (string.class)---getinstance ("Jack").
The following tests assume that we get a byte of a class from a disk or a network, know the package name (REFLCET) and class name (Reflect) and the associated field name and method name of the class, and have been loaded into the project by hot loading.
Method.invoke () will be mentioned in the method below.
class to be tested
Package reflect;/** * @description Runtime acquired class * @author Administrator */public class reflect {public int id;private String NA Me;public Reflect () {this.name = "Tom";} Public Reflect (String name) {this.name = name;} public Reflect (int ID, String name) {this.id = Id;this.name = name;} public void SetName (String name) {this.name = name;} Public String GetName () {return name;} @SuppressWarnings ("unused") private void setId (int id) {this.id = ID;} public int getId () {return ID;} @Overridepublic String toString () {return "ID:" + ID + ", Name:" + Name;}}
Test class
Import static Org.hamcrest.matchers.*;import static Org.junit.assert.*;import Java.lang.reflect.constructor;import Java.lang.reflect.invocationtargetexception;import Java.lang.reflect.method;import Org.junit.After;import Org.junit.before;import Org.junit.test;public class Reflecttest {class<?> clazz;/** * className = "package name. Class Name" */String ClassName = "reflect. Reflect "; @Beforepublic void before () {try {clazz = Class.forName (className);} catch (ClassNotFoundException e) { E.printstacktrace ();}} @Afterpublic void After () {clazz = null;} @Testpublic void TestConstructor () {try {/** *) gets the parameterless constructor */constructor<?> Constructor = Clazz.getconstructor (); O Bject obj = constructor.newinstance (); method = Clazz.getmethod ("GetName"), Assertthat ((String) method.invoke (obj), containsstring ("Tom"));/** * Gets the parameter constructor */constructor = Clazz.getconstructor (string.class); obj = Constructor.newinstance ("Jack"); Assertthat ((String ) Method.invoke (obj), containsstring ("Jack"));/** * Get multiple parameter constructors */constructor = Clazz. GetConstructor (Int.class, string.class); obj = constructor.newinstance (6, "Rose"); method = Clazz.getmethod ("toString Assertthat (String) method.invoke (obj), AllOf (containsstring ("Id:6"), Containsstring ("Name:rose"));} catch (Nosuchmethodexception e) {e.printstacktrace ();} catch (SecurityException e) {e.printstacktrace ();} catch ( Instantiationexception e) {e.printstacktrace (),} catch (Illegalaccessexception e) {e.printstacktrace ();} catch ( IllegalArgumentException e) {e.printstacktrace ();} catch (InvocationTargetException e) {e.printstacktrace ();}}}
Field
The field class is an abstraction of a property or field in a Java generic class. An array of objects representing fields can be obtained through the class GetFields () method, and the object of the field given the name is obtained by GetField (String name) , if the field is decorated identifier private or protected, the GetField () method throws a java.lang.NoSuchFieldException exception . For non-public property settings, you can use the Getdeclaredfield () method and call setaccessible (true)to make the property available.
Test method
@Testpublic void Testfield () {/** * class Newinstance () method invokes the default constructor to create an instance object */object obj = Clazz.newinstance (); method = Clazz.getmethod ("GetName"), Assertthat ((String) method.invoke (obj), containsstring ("Tom"));/** * Set the value of the private property */field Field = Clazz.getdeclaredfield ("name"); Field.setaccessible (true); Field.set (obj, "Jack"); Assertthat (String) method.invoke (obj), containsstring ("Jack"),/** * Sets the value of the public property */field = Clazz.getfield ("id"); Field.setint (obj, 9); method = Clazz.getmethod ("GetId"); Assertthat (string.valueof (Method.invoke (obj)), Containsstring ("9"));} catch (Instantiationexception e) {e.printstacktrace ();} catch (Illegalaccessexception e) {e.printstacktrace ();} catch ( Nosuchmethodexception e) {e.printstacktrace (),} catch (SecurityException e) {e.printstacktrace ();} catch ( IllegalArgumentException e) {e.printstacktrace (),} catch (InvocationTargetException e) {e.printstacktrace ();} catch ( Nosuchfieldexception e) {e.printstacktrace ();}}
Method
The method class is an abstraction of the methods in the Java common class. An array of objects representing the method can be obtained through the class GetMethods () method, via GetMethod (String name, Class<?> ...). Parametertypes) method can get an object that specifies the method name and method of the method parameter type, if the method modifier is private or the Protected,getmethod () method throws Java.lang.NoSuchMethodException exception . For non-public methods, the method can be obtained by using the Getdeclaredmethod () method and calling Setaccessible (true). Call the Method.invoke (object obj, object ... args) method to implement the obj object's call to the method, with the parameter args . As with constructors, theGetMethod () method and the invoke method should correspond. For example GetMethod ("SetName", String.class)---invoke (obj, "Rose").
Test method
@Testpublic void TestMethod () {try {/** *) call the parameterless public method */object obj = clazz.newinstance (); Method method1 = Clazz.getmethod ("GetName"), Assertthat ((String) method1.invoke (obj), containsstring ("Tom"));/** * Called with the public method */method method2 = Clazz.getmethod ("SetName", String.class); Method2.invoke (obj, "Jack"); Assertthat ((String) Method1.invoke (obj), containsstring ("Jack")),/** * Call the private method with parameters */method method3 = Clazz.getdeclaredmethod ("SetId", Int.class); method3.setaccessible (true); Method3.invoke (obj, 5); method = Clazz.getmethod ("GetId"), Assertthat (string.valueof (Method.invoke (obj)), containsstring ("5"));} catch (Instantiationexception e) {e.printstacktrace ();} catch (Illegalaccessexception e) {e.printstacktrace ();} catch ( Nosuchmethodexception e) {e.printstacktrace (),} catch (SecurityException e) {e.printstacktrace ();} catch ( IllegalArgumentException e) {e.printstacktrace ();} catch (InvocationTargetException e) {e.printstacktrace ()}}
class Method Extractor
When a developer learns a class (for example, ArrayList), it can only find methods that are defined or overridden in the class definition by browsing for the source code of the class definition or its JDK document. But for developers, there are probably dozens of more useful ways to inherit from the base class. Finding these methods can be tedious and time-consuming. Fortunately, the reflection mechanism provides a way for developers to write simple tools that can automatically show the full interface. Work in the following ways:
/** * @description class method Extractor * @param clazz */public static void Printclassinfo (Class<?> clazz) {Pattern pattern = Patt Ern.compile (("\\w+\\.")); Constructor<?>[] Constructors = clazz.getconstructors (); Method[] methods = Clazz.getmethods (); field[] fields = Clazz.getdeclaredfields (), for (Field field:fields) {System.out.println (Pattern.matcher ( Field.togenericstring ()). ReplaceAll ("")); for (constructor<?> constructor:constructors) {System.out.println (Pattern.matcher ( Constructor.togenericstring ()). ReplaceAll ("")); for (Method method:methods) {System.out.println (Pattern.matcher (method.togenericstring ()). ReplaceAll (""));}}
Test method test Case: ArrayList
@Testpublic void Testprintclassinfo () {try {classinfo.printclassinfo (Class.forName ("java.util.ArrayList"));} catch ( ClassNotFoundException e) {e.printstacktrace ();}}
Test results:
Private static final long serialversionuidprivate static final int default_capacityprivate static final object[] Empty_ele Mentdataprivate static final object[] Defaultcapacity_empty_elementdatatransient object[] elementdataprivate int sizeprivate static final int max_array_sizepublic ArrayList (collection<? extends e>) public ArrayList () public ArrayList (int) public, Boolean Add (E) public void Add (Int,e), public boolean remove (Object), public e remove (int), public e get ( int) public Object clone () public int indexOf (Object) public void Clear () Public boolean contains (object) public Boolean IsEmpty () public iterator<e> Iterator () public int lastIndexOf (Object) public void ReplaceAll (unaryoperator<e > public int size () public list<e> sublist (int,int) public <T> t[] ToArray (t[]) public object[] ToArray () Public spliterator<e> Spliterator () public boolean addall (int,collection<? extends e>) public boolean AddAll (collection<? extends e>) public void ForEach (CONSUMER<?Super e>) Public E Set (int,e) public void ensurecapacity (int.) public void TrimToSize () public listiterator<e> Listiterator (int) public listiterator<e> Listiterator () public boolean removeall (collection<?>) public Boolean Removeif (predicate<? Super E>) Public boolean retainall (collection<?>) public void sort (Comparator <? Super e>) Public boolean equals (Object) public int hashcode () public String toString () public boolean containsall ( collection<?>) Public final void Wait () throws Interruptedexceptionpublic final void Wait (Long,int) throws Interruptedexceptionpublic final native void wait (long) throws Interruptedexceptionpublic final native class<?> GetClass () Public final native void notify () public final native void Notifyall () public default stream<e> Stream () pub Lic default stream<e> parallelstream ()
JVM
There is nothing magical about the reflection mechanism. When dealing with an object of unknown type through reflection, theJVM simply checks the object. Therefore, the class . class file must be available to the JVM: either on the local machine or on the network. For the reflection mechanism, the. Class file is not available at compile time, so the . Class file is opened and checked at runtime.
Application
Suppose the developer gets a string of bytes from a disk file, or a network connection, and is told that the bytes represent a class. Since this class only appears long after the program has been compiled, the launch mechanism is needed if you want to use this class. Unloading is the scene.
Another scenario for obtaining information about a class at run time, developers want to provide the ability to create and run objects on a remote platform across the network. This is called a remote method call (RMI) which allows a Java program to distribute objects across multiple machines.
When you write a frame, the developer will definitely use reflection, and a simple example is the event bus and annotation framework.
Summary
Reflection is very flexible, in the daily development, careful use of less reflection, reflection will sacrifice part of the performance. When writing a frame, do not shy of reflection, when the key to use reflection to help themselves.
A brief analysis of Java reflection mechanism