The Java reflection mechanism is that in the running state, for any class, you can know all the properties and methods of the class, and for any object, it 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.
In a nutshell, reflection enables you to know the properties and methods of any class at run time.
1 Understanding Class classes and class types
To understand reflection first understand the class, which is the basis of the reflection implementation.
is the 1.1 class an object?
Consider a question:
In an object-oriented world where everything is an object, and an object is an instance of a class, is the class an object?
The answer is yes, the class is an instance object of the Java.lang.Class class, and class is the classes of all classes (there is a class named Class)
1.2 How do I represent a class object?
For ordinary objects, we will typically create and represent this:
new
It says that all classes are objects of class, so how do you do that, in the following ways:
new Class();
But when we look at the source of the class, it's written like this:
/* * Private constructor. Only the Java Virtual Machine creates Class objects. * This constructor is not used and prevents the default constructor being * generated. */ privateClass(ClassLoader loader) { // Initialize final field for classLoader. The initialization value of non-null // prevents future JIT optimizations from assuming this final field is null. classLoader = loader; }
You can see that the constructor is private, and only the JVM can create class objects, so it is not possible to new class objects like normal classes, although we cannot new a class object, but we can get a class object from an existing class, there are three ways, as follows:
Class c1 = Code.class;
This means that any class has an implied static member variable class, which is obtained by obtaining the class's static member variable class.
Class c2 = code1.getClass();
Code1 is an object of code, which is obtained by means of the GetClass () method of the object of a class.
Class c3 = Class.forName("com.trigl.reflect.Code");
This method is called by the class class to invoke the Forname method, which is obtained by the full qualified name of a class
Here, C1, C2, and C3 are all class objects, they are exactly the same, and have a scientific name, called the class type of code.
Here is strange, the front is not to say code is the object of class, and C1, C2, C3 is also the object of class, then code and c1, C2, C3 is not the same? Why is it called code what kind of type? Don't dwell on whether or not they are the same, as long as you understand what the class type is doing, as the name implies, the class type is the type of the class, that is, describe what a class is, what it is, so we can know the properties and methods of a class by the class type, and can invoke the properties and methods of a class. This is the basis of reflection.
class type is the basis of reflection!
class type is the basis of reflection!
Class type is the basis of reflection!
Bold + italic + say three times, this time should remember!
We create an object through the New keyword, but after we know the class type, you can create an object instance of a class with the Newinstance () method of the class type and invoke the method, as follows:
// 需要有无参的构造方法code.print();
So the question is, what's the difference between creating a class from a class type and creating a class from New? The fact that class type creation class is dynamic load class, here is what is dynamic load class.
2 Dynamic Load Class
Program execution is divided into compiler and run time, compile time load a class is called Static load class, runtime load class is called dynamic load class, following an example to explain:
Now aside from the IDE tools, handwritten with Notepad, this is to make it easier for us to manually compile and run a class with the CMD command line to better understand the differences between dynamic load classes and static load classes.
First Write Office.java
class Office{ publicstaticvoidmain(String[] args) { if ("Word".equals(args[0])) { // 静态加载类,在编译时加载 new Word(); w.start(); } if ("Excel".equals(args[0])) { new Excel(); e.start(); } }}
Then go to cmd compile Office.java,
Since our new two classes of Word and Excel are not compiled, the error is that it is the disadvantage of the static load class that all possible classes must be loaded at compile time, and we want to implement which class the runtime uses to load which class, which is improved by dynamically loading the class.
Improved classes: Officebetter.java
class OfficeBetter{ publicstaticvoidmain(String[] args) { try { // 动态加载类,在运行时加载 Class c = Class.forName(args[0]); // 通过类类型,创建该类对象 OfficeAble oa = (OfficeAble)c.newInstance(); oa.start(); } catch (Exception e) { e.printStackTrace(); } } }
The class named Args[0] is dynamically loaded, and Args[0] is the first parameter entered into the Main method at run time. If you enter word then the Word.java will be loaded and you will need to create word.java under the same path as Officebetter.java, so if you enter Excel you will need to load Excel.java.
Where Officeable is an interface, the above dynamically loaded classes such as Word, Excel is implemented officeable, embodies the idea of polymorphism, this dynamic loading and polymorphic thinking can make specific functions and code decoupling, That is, any time you want to add a feature (such as Word and Excel, I want PPT) can be added dynamically, without changing the original code.
Where the Officeable interface is as follows:
interface OfficeAble{ publicvoidstart();}
Word class:
class Word implements OfficeAble{ publicvoidstart() { System.out.println("word...starts..."); }}
Compile and run the above classes sequentially:
3 Getting information about a class
What are the things in a class? The answer is very simple: properties and methods, this section we learn how to get the basic information of the class through the class type.
3.1 Getting member method information for a class
First think about what is included in the Member method: return value type + method name + parameter type
In Java, the member method of a class is also an object, and it is java.lang.reflect.Method
an object, so we java.lang.reflect.Method
get this information through the encapsulated method inside.
3.1.1 Get a method alone
Get Method
Obtaining a method separately is obtained through the following methods of class:
- Public Method Getdeclaredmethod (String name, Class
publicvoidprintint b) { // code body}
Now that you know that a has an object A, you can go through:
Class c = a.getClass();Method method = c.getDeclaredMethod("print"int.class);
To get this method.
how to invoke the obtained method
How do you call this method after you get the method, that is, the code that implements the method as if it were called a normal object method? This is accomplished by means of the method class:
public object invoke (Object obj, object ... args)
The two parameters are the object to which this method belongs and the parameters required by this method, or the above example, by:
"hello"10);
And by ordinary invocation:
a.print("hello"10);
The effect is exactly the same, this is the reflection of the method, and the Invoke () method can in turn use its object as a parameter to invoke the method, completely opposite the normal situation.
3.1.2 Getting information about all member methods in a class
If you want to get information about all the methods in a class other than a single member, you can do so in the following steps:
An object is known to get the class type of its class
Class c = obj.getClass();
Gets all the methods of the class, placed in an array
Method[] methods = c.getDeclaredMethods();
Iterate through an array of methods to get a method
for (Method method : methods)
Gets the class type of the method return value type
Class returnType = method.getReturnType();
Gets the name of the method return value type
String returnTypeName = returnType.getName();
Get the name of the method
String methodName = method.getName();
Get an array of class types for all parameter types
Class[] paramTypes = method.getParameterTypes();
Iterate through an array of class types for a parameter class to get the class type of a parameter Class1
for (Class class1 : paramTypes)
Gets the type name of the parameter
String paramName = class1.getName();
3.2 Getting member variable information for a class
Think about what is included in the member variable: member variable type + member variable name
The member variable of a class is also an object, and it is java.lang.reflect.Field
an object, so we java.lang.reflect.Field
get the information by encapsulating it inside the method.
3.2.1 To get a member variable individually
The following methods of class are implemented:
- Public Field Getdeclaredfield (String name)//Gets all the variables declared by the class itself, excluding the variables of its parent class
- Public Field GetField (String name)//Gets the class from all public member variables, including its parent class variable
The parameter is the name of the member variable.
For example, a Class A has the following member variables:
privateint n;
If a has an object A, then you can get its member variables like this:
Class c = a.getClass();Field field = c.getDeclaredField("n");
3.2.2 Get all the member variables
Similarly, if you want to get information about all member variables, you can do this in the following steps:
An object is known to get the class type of its class
Class c = obj.getClass();
Gets all the member variables of the class, placed in an array
Iterate through the array of variables to get a member variable field
for (Field field : fields)
Gets the class type of the member variable type
Class fieldType = field.getType();
Get the type name of the member variable
String typeName = fieldType.getName();
Get the name of the member variable
String fieldName = field.getName();
3.3 Getting the constructor for a class
And finally think about what is included in the constructor: constructor arguments
As above, the constructor of a class is also an object, and it is java.lang.reflect.Constructor
an object, so we java.lang.reflect.Constructor
can obtain this information by means of the encapsulated method.
3.3.1 Get a constructor individually
The following methods of class are implemented:
- Public Constructor Getdeclaredconstructor (Class
publicAint b) { // code body}
Then you can go through:
int.class);
To get this constructor.
3.3.2 Get all the constructors
The following steps can be implemented:
-
An object is known to get the class type of its class
class C = Obj.getclass ()
;
-
Gets all constructors for the class, placed in an array
constructor[]
constructors = C.getdeclaredconstructors ();
-
Iterates through the array of constructors, obtaining a constructor constructor
for (Constructor constructor:constructors)
-
Get class type array of constructor parameter type
class[] paramtypes = Constructor.getparametertypes ();
-
Iterates through the class type array of the parameter class, obtaining the class type of a parameter Class1
for (Class class1:paramtypes)
-
Get the type name of this parameter
string paramname = Class1.getname ();
4 Understanding the nature of set generics through reflection
The first conclusion is:
Generics in Java are protected from erroneous input and are valid only during the compilation phase, bypassing compilation to run time.
The following is an example to verify:
PackageCom.trigl.reflect;ImportJava.lang.reflect.Method;ImportJava.util.ArrayList;ImportJava.util.List;/** * Nature of collection generics * @description * @author Trigl * @date April 2, 2016 morning 2:54:11 * * Public class genericessence { Public Static void Main(string[] args) {List List1 =NewArrayList ();//No genericsList<string> List2 =NewArraylist<string> ();//There is a generic type /* * 1. First observe the normal way of adding elements, in the compiler check generics, * This time if list2 add int type will error */List2.add ("Hello");//List2.add (20);//Error! List2 has generic restrictions, can only add string, add int errorSystem.out.println ("The length of the List2 is:"+ list2.size ());//At this time the list2 length is 1 / * 2. Then add elements by reflection, dynamically load classes at run time, first get the same class type as List1 and List2 *, and then call the Add method by using method reflection to bypass the compiler to see if you can insert an int * Type element */Class C1 = List1.getclass (); Class C2 = List2.getclass (); SYSTEM.OUT.PRINTLN (C1 = = C2);//Result: True, indicating that the class type is exactly the same //Validation: We can add elements to list2 by reflection of the method, which bypasses the build check Try{Method m = C2.getmethod ("Add", Object.class);//By means of reflection to get the Add methodM.invoke (List2, -);//Add an int to List2, which shows that the compiler will give an error.System.out.println ("The length of the List2 is:"+ list2.size ());//Result: 2, indicating list2 length increased, and no generic check}Catch(Exception e) {E.printstacktrace (); }/ * * As you can see in the compiler, generics limit the type of elements in the collection to be consistent, but after the compiler finishes entering the * run time, generics no longer work, and even different types of elements can be inserted into the collection. */}}
Output results
list2的长度是:1truelist2的长度是:2
Over
Getting Started with Java reflection