What is reflection

JAVA reflection mechanismIn the running state, you can know all the properties and methods of any class. For any object, you can call any of its methods; This ability to dynamically fetch and call methods on objects is called Java’s reflection mechanism.

Java reflection provides the following functions:

  • Determines the class to which any object belongs at runtime

  • Constructs an object of any class at run time

  • Determines which member variables and methods any class has at run time

  • Call a method of any object at run time

Reflection Application Scenario

For example, in Android development, reading the SDK source code, you will find that there are many methods with hide annotations, which are added by Google for security purposes, and the application layer cannot be directly accessed. This can be called at runtime by reflection (Android 9.0 has whitelisted the interface from the blacklist even though reflection is not available).

Implementing custom annotations There are many popular open source frameworks on Android that use custom annotations and reflection, such as EventBus, Retrofit;

Many large apps use the plug-in technology of dynamic loading and hot repair, and also use the way of reflection to realize the call of Host (LibPlugin) to plug-in (LibPlugin). For details, you can understand the open source framework of plug-in, such as VirtualApp, DroidPlugin, RePlugin

Java reflection mechanism

Reflection involves four core classes

  • Java.lang.class. Java: Class object;

  • Java. Lang. Reflect. Constructor. Java: the Constructor of a class object;

  • Java. Lang. Reflect. Method. Java: Method of a class object;

  • Java. Lang. Reflect. Field. Java: attributes of a class object;

To understand the Java reflection mechanism properly, you need to understand the Class Class. Reflection is the operation on the Class Class. When we write a Java program (a Java file), we compile it (generate a class file), and when we run the program, the JVM loads the class file into memory and generates a class object. This Class object is used to obtain the declaration and definition of the parent Class, interface, method, member, and constructor of the Class object that is loaded into the virtual machine. The new form of the object is actually created through these classes.

Reflection works by dynamically accessing and modifying the behavior and state of any Class while the program is running with the aid of class. Java, constructive. Java, Method. Java, and Field. Java classes.

Reflect common apis

1. Get the Class object in reflection

In the Java API, there are three ways to get Class objects:

First, use the class.forname static method. You can use this method to get Class objects when you know the full pathname of the Class.

Class clz = Class.forName("java.lang.String");
Copy the code

Second, use the.class method. This approach is only suitable for classes where the operation is known before compilation.

Class clz = String.class;
Copy the code

Third, use the getClass() method of the class object.

String str = new String("Hello");
Class clz = str.getClass();
Copy the code

Create class objects by reflection

There are two main ways to create Class objects through reflection: through the newInstance() method of a Class object and through the newInstance() method of a Constructor object.

The first is through newInstance() on Class objects.

Class clz = Stock.class;
Stock stock = (Stock)clz.newInstance();
Copy the code

Second: newInstance() via the Constructor object

Class clz = Stock.class;
Constructor constructor = clz.getConstructor();
Stock stock = (Stock)constructor.newInstance();
Copy the code

Class objects created from a Constructor object can select a specific Constructor, whereas only the default no-argument Constructor can be used from a Class object. The following code calls a constructor with arguments to initialize the class object.

Class clz = Stock.class; Constructor constructor = clz.getConstructor(String.class, String.class,String.class); Stock = (Stock)constructor. NewInstance ("000001", "sz");Copy the code

3. Get class attributes, methods, and constructors by reflection

We get properties from the Class objects using the getFields() and getDeclaredFields() methods, and methods from getMethod() and getDeclaredMethod.

Methods with Declared color{red}{Declared}Declared can only obtain properties or methods of the class itself, including those that are private. Methods without Declared cannot obtain private properties or methods, but include all public properties or methods of the parent class as well as its own.

Class clz = Stock.class; Field[] fields = clz.getFields(); Field[] declaredFields = clz.getDeclaredFields(); clz.declaredFields (); [] methods = clz.getMethods(); [] declaredMethods = clz.getDeclaredMethods(); // declaredMethods = clz.getDeclaredMethods(); // Public and private methods of its ownCopy the code

4. Get attribute values and execution methods by reflection

Class stockClass= Stock.class; Object stockObject = stockClass.newInstance(); Field marketField = stockClass.getDeclaredField("market"); marketField.setAccessible(true); // Private properties or methods must be set accessible=true, Log. I (TAG, "reflectPrivateField:" + MarketField. get(stockObject)); Method method = stockClass.getDeclaredMethod("getTrend", String.class); method.setAccessible(true); Object trend = method.invoke(stockObject, "5"); Log.i(TAG, "reflectPrivateMethod:" + trend);Copy the code

Complete code example

Prodct.java

public class Product { private String mCode; private String mName; public String type; public void setCode(String code) { mCode = code; } public void setName(String name) { mName = name; } public String getCode() { return mCode; } public String getName() { return mName; } public String toString() { return "Product{code=" + mCode + ",name=" + mName + ",type=" + type + "}"; }}Copy the code

Stock.java

public class Stock extends Product { private String market = "sz"; private int getTrend(String price) { if (TextUtils.isEmpty(price)) { return 0; } else if (price.contains("-")) { return -1; } else { return 1; } } @Call("do_sth_call") public void doSth() { Log.i("Stock", "do sth call"); } public String toString() { return "Stock{code=" + getCode() + ",name=" + getName() + ",type=" + type + ",market=" + market + "}"; }}Copy the code

Call.java

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Call {
    String value();
}
Copy the code

ReflectTest.java

public class ReflectTest { public static final String TAG = "reflect"; public static void testReflect() { reflectNewInstance(); reflectPrivateField(); reflectPrivateMethod(); reflectAnnotation(); reboot(); } /** * Creating an object */ public static void reflectNewInstance() {try {Class<? > stockClass = Class.forName("com.demo.reflect.Stock"); Object stockObject = stockClass.newInstance(); Product product = (Product) stockObject; product.setCode("000001"); Product.setname (" Ping an Bank "); product.type = "1"; Log.i(TAG, "reflectNewInstance stock=" + product.toString()); } catch (Exception e) { Log.e(TAG, e.getMessage()); }} /** * reflectPrivateField() {try {Class<? > stockClass = Class.forName("com.demo.reflect.Stock"); Object stockObject = stockClass.newInstance(); Field marketField = stockClass.getDeclaredField("market"); marketField.setAccessible(true); Log.i(TAG, "reflectPrivateField:" + marketField.get(stockObject)); } catch (Exception e) { Log.e(TAG, e.getMessage()); }} /** * Private method */ public static void reflectPrivateMethod() {try {Class<? > stockClass = Class.forName("com.demo.reflect.Stock"); Object stockObject = stockClass.newInstance(); Method method = stockClass.getDeclaredMethod("getTrend", String.class); method.setAccessible(true); Object trend = method.invoke(stockObject, "5"); Log.i(TAG, "reflectPrivateMethod:" + trend); } catch (Exception e) { Log.e(TAG, e.getMessage()); Public static void reflectAnnotation() {try {Class<? > stockClass = Class.forName("com.demo.reflect.Stock"); Object stockObject = stockClass.newInstance(); Method[] methods = stockClass.getMethods(); for (Method method : methods) { Call call = method.getAnnotation(Call.class); if (call ! = null && "do_sth_call".equals(call.value())) { method.invoke(stockObject); }}} catch (Exception e) {}} public static void reboot() {try {Class<? > cServiceManager = Class.forName("android.os.ServiceManager"); Method mGetService = cServiceManager.getMethod("getService", String.class); Object oPowerManagerService = mGetService.invoke(null, Context.POWER_SERVICE); Class<? > cIPowerManagerStub = Class.forName("android.os.IPowerManager$Stub"); Method mReboot = cIPowerManagerStub.getMethod("reboot", boolean.class, String.class, boolean.class); Method mAsInterface = cIPowerManagerStub.getMethod("asInterface", IBinder.class); Object oIPowerManager = mAsInterface.invoke(null, oPowerManagerService); mReboot.invoke(oIPowerManager, true, null, true); } catch (Exception ex) { ex.printStackTrace(); }}}Copy the code

Reflection execution reboot method throws an exception, Java. Lang. Reflect. InvocationTargetException, abnormal reason is Java. Lang. SecurityException: Neither the user nor 10547 current process from android. Permission. REBOOT. The reason is that you do not have the operation permission to reboot.

 Caused by: java.lang.SecurityException: Neither user 10547 nor current process has android.permission.REBOOT.
W/System.err:     at android.os.IPowerManager$Stub$Proxy.reboot(IPowerManager.java:1596)
W/System.err:     at com.android.server.power.PowerManagerService$BinderService.reboot(PowerManagerService.java:5662)
Copy the code

conclusion

This article summarizes the functions and application scenarios of reflection, lists commonly used apis, and gives code examples. Reflection has both advantages and disadvantages.

The advantage is that it provides a flexible mechanism to do whatever you want with a class. Some dark technologies use reflection to achieve functions that normal development cannot achieve, and many frameworks use reflection to make development more convenient and efficient.

Defect is in the running process through reflection method than direct call time-consuming operation, depending on how the reflection, generally can be ignored, another problem is security, modify private property and access private methods, destroyed the encapsulation of a class, could potentially logic hidden trouble, another is on the android applications, adaptation problem may come up. Therefore, the impact of these disadvantages should be fully understood before using reflection.

reference

Deep reflections come from shallow ones

Baymax: Java Reflection: Getting started, Using, and Working Principles

java.lang.Class

java.lang.reflect.Method

Pay attention to the public number “code farmers turn over record”, reply 888, free technical information. After paying attention, you will receive high quality technology and job sharing from time to time, I hope to accompany you to move forward with your dream.