Introduction to the reflection mechanism and application scenarios of Java learning

  • 2020-05-17 05:30:36
  • OfStack

Preface:

Recently, the company is carrying out business componentization process, in which the routing implementation USES the reflection mechanism of Java. Since it has been used, I want to learn and summarize 1 well. In fact, both the previous version of EventBus 2.x, Retrofit and the early annotation framework of View all more or less use the reflection mechanism of Java.

What is the Java reflection mechanism?

JAVA reflection mechanism is in the running state, for any one class, can know all the attributes and methods of this class; For any one object, you can call any one of its methods. This ability to dynamically fetch and dynamically call methods on an object is called Java's reflection mechanism.

What does the reflection mechanism provide?

Determines which class any one object belongs to at run time Construct the object of any one class at runtime. Determine the member variables and methods of any one class at run time. Call methods on any one object at run time; Generate dynamic proxy;

Java reflection mechanism class:


java.lang.Class; // class         
java.lang.reflect.Constructor;// A constructor  
java.lang.reflect.Field; // class     
java.lang.reflect.Method;// Methods of a class 
java.lang.reflect.Modifier;// Access permissions 

Java reflection mechanism implementation:
1.) acquisition of class objects


// The first 1 Kind of way   Through object getClass methods 
Person person = new Person();
Class<?> class1 = person.getClass();
// The first 2 Kind of way   Through the class class attribute 
class1 = Person.class;
try {
  // The first 3 Kind of way   through Class Class static methods -- forName() To implement the 
  class1 = Class.forName("com.whoislcj.reflectdemo.Person");
} catch (ClassNotFoundException e) {
  e.printStackTrace();
}

2.) get the summary information of the class object


boolean isPrimitive = class1.isPrimitive();// Determine if it is the base type 
boolean isArray = class1.isArray();// Determine if it is a collection class 
boolean isAnnotation = class1.isAnnotation();// Determines if it is an annotation class 
boolean isInterface = class1.isInterface();// Determine if it is an interface class 
boolean isEnum = class1.isEnum();// Determines if it is an enumeration class 
boolean isAnonymousClass = class1.isAnonymousClass();// Determines whether an anonymous inner class is present 
boolean isAnnotationPresent = class1.isAnnotationPresent(Deprecated.class);// Determines whether it is modified by an annotation class 

String className = class1.getName();// To obtain class The name   Contains the package name path 
Package aPackage = class1.getPackage();// To obtain class The package information 
String simpleName = class1.getSimpleName();// To obtain class The name of the class 
int modifiers = class1.getModifiers();// To obtain class Access permissions 

Class<?>[] declaredClasses = class1.getDeclaredClasses();// The inner class 
Class<?> declaringClass = class1.getDeclaringClass();// Outside class 

3.) get the properties, methods, constructors, etc. of class object


Field[] allFields = class1.getDeclaredFields();// To obtain class All properties of the object 
Field[] publicFields = class1.getFields();// To obtain class The object's public attribute 
try {
  Field ageField = class1.getDeclaredField("age");// To obtain class Specify the attributes 
  Field desField = class1.getField("des");// To obtain class The specified public attribute 
} catch (NoSuchFieldException e) {
  e.printStackTrace();
}

Method[] methods = class1.getDeclaredMethods();// To obtain class All declaration methods of the object 
Method[] allMethods = class1.getMethods();// To obtain class All methods of the   Includes methods of the parent class 

Class parentClass = class1.getSuperclass();// To obtain class The parent class of the object 
Class<?>[] interfaceClasses = class1.getInterfaces();// To obtain class All interfaces of the object 

Constructor<?>[] allConstructors = class1.getDeclaredConstructors();// To obtain class All declaration constructors of the object 
Constructor<?>[] publicConstructors = class1.getConstructors();// To obtain class object public The constructor 
try {
  Constructor<?> constructor = class1.getDeclaredConstructor(new Class[]{String.class});// Gets the specified declaration constructor 
  Constructor publicConstructor = class1.getConstructor(new Class[]{});// Gets the specified declared public The constructor 
} catch (NoSuchMethodException e) {
  e.printStackTrace();
}

Annotation[] annotations = class1.getAnnotations();// To obtain class All annotations of the object 
Annotation annotation = class1.getAnnotation(Deprecated.class);// To obtain class Object specified annotation 

Type genericSuperclass = class1.getGenericSuperclass();// To obtain class Object of the immediate superclass  Type
Type[] interfaceTypes = class1.getGenericInterfaces();// To obtain class Object of all interfaces type A collection of 

4.) class object is generated dynamically


// The first 1 Kind of way  Class The object newInstance() Method to generate 
Object obj = class1.newInstance();
// The first 2 Kind of way   The object gets the corresponding Constructor Object and pass through the Constructor The object's newInstance() Method to generate 
Constructor<?> constructor = class1.getDeclaredConstructor(new Class[]{String.class});// Gets the specified declaration constructor 
obj = constructor.newInstance(new Object[]{"lcj"});

5.) call functions dynamically


try {
  //  Generate a new object: with newInstance() methods 
  Object obj = class1.newInstance();
  // Determine whether the object is Person A subclass of 
  boolean isInstanceOf = obj instanceof Person;
  // The first thing you need to do is get the one that corresponds to this method Method object 
  Method method = class1.getDeclaredMethod("setAge", new Class[]{int.class});
  // Calls the specified function and passes the arguments 
  method.invoke(obj, 28);
  method = class1.getDeclaredMethod("getAge");
  Object result = method.invoke(obj, new Class[]{});
} catch (InstantiationException e) {
  e.printStackTrace();
} catch (IllegalAccessException e) {
  e.printStackTrace();
} catch (NoSuchMethodException e) {
  e.printStackTrace();
} catch (InvocationTargetException e) {
  e.printStackTrace();
}

6.) get generic types through reflection

For example, the following structure


//People class 
public class People<T> {}
//Person Class inheritance People class 
public class Person<T> extends People<String> implements PersonInterface<Integer> {}
//PersonInterface interface 
public interface PersonInterface<T> {}

Gets the generic type


Person<String> person = new Person<>();
// The first 1 Kind of way   Through object getClass methods 
Class<?> class1 = person.getClass();
Type genericSuperclass = class1.getGenericSuperclass();// To obtain class Object of the immediate superclass  Type
Type[] interfaceTypes = class1.getGenericInterfaces();// To obtain class Object of all interfaces Type A collection of 

getComponentType(genericSuperclass);
getComponentType(interfaceTypes[0]);

getComponentType implementation


private Class<?> getComponentType(Type type) {
Class<?> componentType = null;
if (type instanceof ParameterizedType) {
  //getActualTypeArguments() Returns the value that represents the actual type parameter of this type  Type  An array of objects. 
  Type[] actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();
  if (actualTypeArguments != null && actualTypeArguments.length > 0) {
  componentType = (Class<?>) actualTypeArguments[0];
  }
} else if (type instanceof GenericArrayType) {
  //  said 1 An element type is a parameterized type or an array type of a type variable 
  componentType = (Class<?>) ((GenericArrayType) type).getGenericComponentType();
} else {
  componentType = (Class<?>) type;
}
return componentType;
}

6.) get annotation information through reflection mechanism

The emphasis here is on obtaining the annotation information of Method as an example


try {
  // The first thing you need to do is get the one that corresponds to this method Method object 
  Method method = class1.getDeclaredMethod("jumpToGoodsDetail", new Class[]{String.class, String.class});
  Annotation[] annotations1 = method.getAnnotations();// Get all method annotation information 
  Annotation annotation1 = method.getAnnotation(RouterUri.class);// Gets the specified annotation information 
  TypeVariable[] typeVariables1 = method.getTypeParameters();
  Annotation[][] parameterAnnotationsArray = method.getParameterAnnotations();// Get all the parameter annotation information 
  Class<?>[] parameterTypes = method.getParameterTypes();// Get all the parameters class type 
  Type[] genericParameterTypes = method.getGenericParameterTypes();// Gets all the parameters type type 
  Class<?> returnType = method.getReturnType();// Gets the return type of the method 
  int modifiers = method.getModifiers();// Gets access to a method 
} catch (NoSuchMethodException e) {
  e.printStackTrace();
}

Application scenarios of reflection mechanism:

Reverse code, such as decompile Frameworks that combine annotations, such as Retrofit Pure reflection mechanism application framework such as EventBus 2.x Dynamically generate a class framework such as Gson

Advantages and disadvantages of reflection mechanism:

Advantages: runtime type determination, dynamic class loading, dynamic proxy using reflection.

Cons: performance is a problem, reflection is equivalent to a series 1 explain operation, notifying jvm what to do, performance is much slower than direct java code.

Conclusion:

The reflection mechanism of Java is rarely used in the normal business development process, but it is widely used in the construction of some basic frameworks. Today, I have simply summarized and learned 1. There are still a lot of unknown knowledge to be used and supplemented later.


Related articles: