preface

  • Reflection in Java helps programs do a lot of things, getting all the properties and methods of a class in the running state.
  • Public and private variables and methods, constructors, and other information in a class can be retrieved by reflection

Class: getDeclaredField reflects all attributes of a Class (including public, private, static, and final). GetDeclaredClasses reflects all inner class objects of the class. GetDeclaredMethod reflects all methods of the class. SetAccessible (true) Disables Java language access checks. If you want to retrieve private members, set this value to true. This is unsafe but improves reflection efficiency.

Get an Integer class private attribute by reflection

  • Final properties can be assigned
  • Here we take the value property of the Integer class object, assign it a value, and the result of that execution is to fix the value we set for us
public static void main (String[] args) throws Exception { Class<Integer> aClass = Integer.class; Field cache = aClass.getDeclaredField("value"); cache.setAccessible(true); Integer a = 10, b = 10; cache.set(a, 16); System.out.println(a); cache.set(b, 12); System.out.println(b); } ------------------ Result 16 12Copy the code

Exit tips

  • Write the cached value inside the Integer to a fixed block of static code.
static { try { final Class<? >[] declaredClasses = Integer.class.getDeclaredClasses(); Class<? > integerClass = declaredClasses[0]; Field cache = integerClass.getDeclaredField("cache"); cache.setAccessible(true); Integer[] integer = (Integer[]) cache.get(integerClass); for (int i = 0; i < integer.length; i++) { integer[i] = 3; } } catch (NoSuchFieldException | IllegalAccessException e) { } } public static void main (String[] args) throws Exception {// new Integer() creates a new space in the heap, Println (new Integer(2)); system.out.println (new Integer(2)); System.out.println(Integer.valueOf(2)); Valueof () Integer A = 0; System.out.println(a); Integer c = 127; System.out.println(c); Integer d = 128; System.out.println(d); Integer e = 129; System.out.println(e); } -------------- Result 2 3 3 3 3 128 129Copy the code

Get the String private property by reflection

  • In JDK8 a string holds its character contents as an array of char, so some undescribable operation is performed on the value attribute by reflection, which results in the following
public static void main (String[] args) throws Exception { String a = "a"; Class<? > stringClass = String.class; Field field = stringClass.getDeclaredField("value"); field.setAccessible(true); char[] chars = (char[]) field.get(a); Chars [0] = 'zheng '; System.out.println(a); } -------------- Run the print result zhengCopy the code

Get private attributes of a class by reflection

  • Preliminary Preparation
/** * @Author: ZRH * @Date: 2021/11/19 15:09 */ @Data public class TestModel { private Integer id; private String name; public TestModel () { } public TestModel (String name, Integer id) { this.name = name; this.id = id; } private String sendFun (String name) { return "OK - " + name; }}Copy the code
public static void main (String[] args) throws Exception { TestModel model = new TestModel(); Class<? > aClass = TestModel.class; Field nameField = aClass.getDeclaredField("name"); nameField.setAccessible(true); nameField.set(model, "zrh"); Field idField = aClass.getDeclaredField("id"); idField.setAccessible(true); idField.set(model, 10000); System.out.println(model.toString()); } -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- the execution result TestModel (id = 10000, name = ZRH)Copy the code

Get the constructor of the class by reflection

Public static void main (String[] args) throws Exception {// Obtain the current Class object Class aClass = testModel.class; Constructor = aclass.getconstructor (string.class, integer.class); // Get the Constructor specified for the current class. TestModel model = (TestModel) constructor.newinstance ("222", 3); System.out.println(model); // Get the instance object model = (TestModel) aclass.newinstance () by using the default no-argument constructor of the current class; model.setId(2); model.setName("111"); System.out.println(model); } -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- the execution result TestModel (id = 3, name = 222) TestModel (id = 2, name = 111).Copy the code

Get the Capacity private property of the LinkedBlockingQueue by reflection

  • A previous article “Dynamic Parameter Configuration for Thread Pool Tuning” described that if you wanted to dynamically configure the queue size of a thread pool, you would need to copy and rewrite it and release the setCapacity operation of its Capacity property.
  • The capacity attribute can also be reflected and reassigned, as shown in the following example:
public static void main (String[] args) throws Exception { final LinkedBlockingQueue<Object> queue = new LinkedBlockingQueue<>(3); for (int i = 0; i < 5; i++) { queue.offer(i); } System.out.println("before size = " + queue.size()); final Class<LinkedBlockingQueue> queueClass = LinkedBlockingQueue.class; final Field field = queueClass.getDeclaredField("capacity"); field.setAccessible(true); field.set(queue, 5); for (int i = 0; i < 8; i++) { queue.offer(i); } System.out.println("after size = " + queue.size()); } -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- the execution result before size = 3 after size = 5Copy the code
  • The current queue has an initial size of 3, and after reflection and reassignment of capacity to 5, elements are reinserted into the queue until it has a size of 5.

Get the class’s private methods by reflection

  • Get the current class object, then getDeclaredMethod get its method object, and finally call
Public static void main (String[] args) throws Exception {// Obtain the class instance object final TestModel Model = new TestModel(); Final Class<? > aClass1 = model.getClass(); / / to get final Method of object of the class Method sendFun = aClass1. GetDeclaredMethod (" sendFun ", String. Class); // Private methods need to disable Java language access check sendFun.setaccessible (true); ZRH = sendfun.invoke (model, "ZRH "); ZRH = sendfun.invoke (model," ZRH "); System.out.println(zrh); } --------------- Result ok-zrhCopy the code

The last

  • Learn with an open mind and make progress together