Home Java javaTutorial In-depth explanation of Java reflection mechanism

In-depth explanation of Java reflection mechanism

Jun 23, 2017 pm 04:38 PM
java reflection mechanism go deep Detailed explanation

1. Concept

Reflection is to map various components of Java into corresponding Java classes.

The construction method of the Class class is private and is created by the JVM.

Reflection is a feature of the Java language, which allows the program to perform self-checks and operate internal members during runtime (note not compilation time). For example, it allows a Java class to obtain all its member variables and methods and display them. This capability of Java may not be used much in practical applications, but this feature does not exist at all in other programming languages. For example, in Pascal, C, or C++ there is no way to obtain information about function definitions in a program. (From Sun)

JavaBean is one of the practical applications of reflection, which allows some tools to visually operate software components. These tools dynamically load and obtain the properties of Java components (classes) through reflection.

Reflection has been around since 1.2. The next three major frameworks will all use the reflection mechanism. When it comes to the class "Class", you cannot directly new CLass(). Its object is a bytecode in the memory. . 

 Instances of the Class class represent classes and interfaces in a running Java application. An enumeration is a class and an annotation is an interface. Each array belongs to a class that is mapped to a Class object, which is shared by all arrays with the same element type and dimension. The basic Java types (boolean, byte, char, short, int, long, float, and double) and the keyword void are also represented as Class objects. Class has no public constructor. Class objects are automatically constructed by the Java virtual machine when a class is loaded and by calling the defineClass method in the class loader.

1 Person p1 = new Person();
2 //下面的这三种方式都可以得到字节码
3 CLass c1 = Date.class();
4 p1.getClass(); 
5 //若存在则加载,否则新建,往往使用第三种,类的名字在写源程序时不需要知道,到运行时再传递过来
6 Class.forName("java.lang.String");
Copy after login

CLass.forName() bytecode has been loaded into the java virtual machine to get the bytecode; the bytecode has not yet been generated in the java virtual machine and is processed using the class loader Loading, the loaded bytecode is buffered into the virtual machine.

Consider the following simple example and let's see how reflection works.

import java.lang.reflect.*;  

public class DumpMethods {  
   public static void main(String args[]) {  
      try {  
           Class c = Class.forName("java.util.Stack");  

           Method m[] = c.getDeclaredMethods();  
             
           for (int i = 0; i < m.length; i++)  
               System.out.println(m[i].toString());  
      }  
      catch (Throwable e){  
            System.err.println(e);  
      }  
   }  
}
Copy after login

1 public synchronized java.lang.Object java.util.Stack.pop() 
2 public java.lang.Object java.util.Stack.push(java.lang.Object) 
3 public boolean java.util.Stack.empty() 
4 public synchronized java.lang.Object java.util.Stack.peek() 
5 public synchronized int java.util.Stack.search(java.lang.Object)
Copy after login

 

This lists the method names of the java.util.Stack class and their Qualifiers and return types. This program uses Class.forName to load the specified class and then calls getDeclaredMethods to get the list of methods defined in the class. java.lang.reflect.Methods is a class used to describe a single method in a class.

The following example uses the Class object to display the class name of the object:

1 void printClassName(Object obj) {
2          System.out.println("The class of " + obj +
3                             " is " + obj.getClass().getName());
4      }
Copy after login

You can also use a class literal (JLS Section 15.8.2) to obtain the specified type ( or void) Class object. For example:

1 System.out.println("The name of class Foo is: "+Foo.class.getName());
Copy after login

When there is no object instance, there are two main methods.

//获得类类型的两种方式        
Class cls1 = Role.class;        
Class cls2 = Class.forName("yui.Role");
Copy after login

Note that in the second method, the parameter in forName must be the complete class name (package name + class name), and this method needs to catch exceptions. Now that you have cls1, you can create an instance of the Role class. Using the newInstance method of Class is equivalent to calling the default constructor of the class.

1 Object o = cls1.newInstance(); 
2 //创建一个实例        
3 //Object o1 = new Role();   //与上面的方法等价
Copy after login

2. Commonly used methods

 1.isPrimitive (determine whether it is a basic type of bytecode)

public class TestReflect {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        String str = "abc";
        Class cls1 = str.getClass();
        Class cls2 = String.class;
        Class cls3 = null;//必须要加上null
        try {
            cls3 = Class.forName("java.lang.String");
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println(cls1==cls2);
        System.out.println(cls1==cls3);
        
        System.out.println(cls1.isPrimitive());
        System.out.println(int.class.isPrimitive());//判定指定的 Class 对象是否表示一个基本类型。
        System.out.println(int.class == Integer.class);
        System.out.println(int.class == Integer.TYPE);
        System.out.println(int[].class.isPrimitive());
        System.out.println(int[].class.isArray());
    }
}
/*
 * true
true
false
true
false
true
false
true

 */
*/
Copy after login

 2.getConstructor and getConstructors()

There is no order of construction methods in Java, and they are distinguished by type and number of parameters. 

1 public class TestReflect {
2     public static void main(String[] args) throws SecurityException, NoSuchMethodException {
3         // TODO Auto-generated method stub
4         String str = "abc";
5         
6         System.out.println(String.class.getConstructor(StringBuffer.class));
7     }
8 }
Copy after login

  3. The Filed class represents a member variable in a certain class.

 1 import java.lang.reflect.Field;
 2 public class TestReflect {
 3     public static void main(String[] args) throws SecurityException, NoSuchMethodException, NoSuchFieldException, IllegalArgumentException, Exception {
 4         ReflectPointer rp1 = new ReflectPointer(3,4);
 5         Field fieldx = rp1.getClass().getField("x");//必须是x或者y
 6         System.out.println(fieldx.get(rp1));
 7         
 8         /*
 9          * private的成员变量必须使用getDeclaredField,并setAccessible(true),否则看得到拿不到
10          */
11         Field fieldy = rp1.getClass().getDeclaredField("y");
12         fieldy.setAccessible(true);//暴力反射
13         System.out.println(fieldy.get(rp1));
14         
15     }
16 }
17 
18 class ReflectPointer {
19     
20     public int x = 0;
21     private int y = 0;
22     
23     public ReflectPointer(int x,int y) {//alt + shift +s相当于右键source
24         super();
25         // TODO Auto-generated constructor stub
26         this.x = x;
27         this.y = y;
28     }
29 }
Copy after login

 4.

3. Typical examples

 1. Change b in all String type member variables to a.

 1 import java.lang.reflect.Field;
 2 public class TestReflect {
 3     public static void main(String[] args) throws SecurityException, NoSuchMethodException, NoSuchFieldException, IllegalArgumentException, Exception {
 4         ReflectPointer rp1 = new ReflectPointer(3,4);
 5         changeBtoA(rp1);
 6         System.out.println(rp1);
 7         
 8     }
 9     
10     private static void changeBtoA(Object obj) throws RuntimeException, Exception {
11         Field[] fields = obj.getClass().getFields();
12         
13         for(Field field : fields) {
14             //if(field.getType().equals(String.class))
15             //由于字节码只有一份,用equals语义不准确
16             if(field.getType()==String.class) {
17                 String oldValue = (String)field.get(obj);
18                 String newValue = oldValue.replace(&#39;b&#39;, &#39;a&#39;);
19                 field.set(obj,newValue);
20             }
21         }
22     }
23 }
24 
25 class ReflectPointer {
26     
27     private int x = 0;
28     public int y = 0;
29     public String str1 = "ball";
30     public String str2 = "basketball";
31     public String str3 = "itcat";
32     
33     public ReflectPointer(int x,int y) {//alt + shift +s相当于右键source
34         super();
35         // TODO Auto-generated constructor stub
36         this.x = x;
37         this.y = y;
38     }
39 
40     @Override
41     public String toString() {
42         return "ReflectPointer [str1=" + str1 + ", str2=" + str2 + ", str3="
43                 + str3 + "]";
44     }
45 }
Copy after login

 2. Write a program to call the main method in the class based on the class name provided by the user.

Why use reflection?

 1 import java.lang.reflect.Field;
 2 import java.lang.reflect.Method;
 3 
 4 public class TestReflect {
 5     public static void main(String[] args) throws SecurityException, NoSuchMethodException, NoSuchFieldException, IllegalArgumentException, Exception {
 6         String str = args[0];
 7         /*
 8          * 这样会数组角标越界,因为压根没有这个字符数组
 9          * 需要右键在run as-configurations-arguments里输入b.Inter(完整类名)
10          * 
11          */
12         Method m = Class.forName(str).getMethod("main",String[].class);
13         //下面这两种方式都可以,main方法需要一个参数
14         
15         m.invoke(null, new Object[]{new String[]{"111","222","333"}});
16         m.invoke(null, (Object)new String[]{"111","222","333"});//这个可以说明,数组也是Object
17         /*
18          * m.invoke(null, new String[]{"111","222","333"})
19          * 上面的不可以,因为java会自动拆包
20          */
21     }
22 }
23 
24 class Inter {
25     public static void main(String[] args) {
26         for(Object obj : args) {
27             System.out.println(obj);
28         }
29     }
30 }
Copy after login

 3. Simulate the instanceof operator

class S {  
}   

public class IsInstance {  
   public static void main(String args[]) {  
      try {  
           Class cls = Class.forName("S");  
           boolean b1 = cls.isInstance(new Integer(37));  
           System.out.println(b1);  
           boolean b2 = cls.isInstance(new S());  
           System.out.println(b2);  
      }  
      catch (Throwable e) {  
           System.err.println(e);  
      }  
   }  
}
Copy after login

 

 In this example, a Class object of class S is created , and then checks whether some object is an instance of S. Integer(37) is not, but new S() is.

4. Method class

Represents a method in a class (not an object).

 1 import java.lang.reflect.Field;
 2 import java.lang.reflect.Method;
 3 /*
 4  * 人在黑板上画圆,涉及三个对象,画圆需要圆心和半径,但是是私有的,画圆的方法
 5  * 分配给人不合适。
 6  * 
 7  * 司机踩刹车,司机只是给列车发出指令,刹车的动作还需要列车去完成。
 8  * 
 9  * 面试经常考面向对象的设计,比如人关门,人只是去推门。
10  * 
11  * 这就是专家模式:谁拥有数据,谁就是专家,方法就分配给谁
12  */
13 public class TestReflect {
14     public static void main(String[] args) throws SecurityException, NoSuchMethodException, NoSuchFieldException, IllegalArgumentException, Exception {
15         String str = "shfsfs";
16         //包开头是com表示是sun内部用的,java打头的才是用户的
17         Method mtCharAt = String.class.getMethod("charAt", int.class);
18         Object ch = mtCharAt.invoke(str,1);//若第一个参数是null,则肯定是静态方法
19         System.out.println(ch);
20         
21         System.out.println(mtCharAt.invoke(str, new Object[]{2}));//1.4语法
22         
23     }
24     
25 }
Copy after login

5. Array reflection

The Array tool class is used to complete the reflection operation of the array.

The same type and latitude have the same bytecode.

int.class and Integer.class are not the same bytecode, Integer.TYPE, TYPE represents the bytecode of the basic class corresponding to the packaging class int.class==Integer.TYPE

 1 import java.util.Arrays;
 2 
 3 /*
 4  * 从这个例子看出即便字节码相同但是对象也不一定相同,根本不是一回事
 5  * 
 6  */
 7 public class TestReflect {
 8     public static void main(String[] args) throws SecurityException, NoSuchMethodException, NoSuchFieldException, IllegalArgumentException, Exception {
 9         int[] a = new int[3];
10         int[] b = new int[]{4,5,5};//直接赋值后不可以指定长度,否则CE
11         int[][] c = new int[3][2];
12         String[] d = new String[]{"jjj","kkkk"};
13         System.out.println(a==b);//false
14         System.out.println(a.getClass()==b.getClass());//true
15         //System.out.println(a.getClass()==d.getClass());    //比较字节码a和cd也没法比
16         System.out.println(a.getClass());//输出class [I
17         System.out.println(a.getClass().getName());//输出[I,中括号表示数组,I表示整数
18         
19         System.out.println(a.getClass().getSuperclass());//输出class java.lang.Object
20         System.out.println(d.getClass().getSuperclass());//输出class java.lang.Object
21         
22         //由于父类都是Object,下面都是可以的
23         Object obj1 = a;//不可是Object[]
24         Object obj2 = b;
25         Object[] obj3 = c;//基本类型的一位数组只可以当做Object,非得还可以当做Object[]
26         Object obj4 = d;
27         
28         //注意asList处理int[]和String[]的区别
29         System.out.println(Arrays.asList(b));//1.4没有可变参数,使用的是数组,[[I@1bc4459]
30         System.out.println(Arrays.asList(d));//[jjj, kkkk]
31         
32     }
33 }
Copy after login

6. Conclusion
The above is the simple use of the reflection mechanism. Obviously friends who have studied spring must understand why we can obtain the specified methods and variables through the configuration file when we create the object. It is all implemented by passing in string, just like what you need, we will produce it for you, and we have been using Object, which shows that the dynamic characteristics of the Java language and the dependence are greatly reduced.

#Attention, students who are learning Java! ! !
If you encounter any problems during the learning process or want to obtain learning resources, you are welcome to join the Java learning exchange group: 159610322 Let’s learn Java together!

The above is the detailed content of In-depth explanation of Java reflection mechanism. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
1 months ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
1 months ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
1 months ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Chat Commands and How to Use Them
1 months ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Perfect Number in Java Perfect Number in Java Aug 30, 2024 pm 04:28 PM

Guide to Perfect Number in Java. Here we discuss the Definition, How to check Perfect number in Java?, examples with code implementation.

Random Number Generator in Java Random Number Generator in Java Aug 30, 2024 pm 04:27 PM

Guide to Random Number Generator in Java. Here we discuss Functions in Java with examples and two different Generators with ther examples.

Weka in Java Weka in Java Aug 30, 2024 pm 04:28 PM

Guide to Weka in Java. Here we discuss the Introduction, how to use weka java, the type of platform, and advantages with examples.

Smith Number in Java Smith Number in Java Aug 30, 2024 pm 04:28 PM

Guide to Smith Number in Java. Here we discuss the Definition, How to check smith number in Java? example with code implementation.

Java Spring Interview Questions Java Spring Interview Questions Aug 30, 2024 pm 04:29 PM

In this article, we have kept the most asked Java Spring Interview Questions with their detailed answers. So that you can crack the interview.

Break or return from Java 8 stream forEach? Break or return from Java 8 stream forEach? Feb 07, 2025 pm 12:09 PM

Java 8 introduces the Stream API, providing a powerful and expressive way to process data collections. However, a common question when using Stream is: How to break or return from a forEach operation? Traditional loops allow for early interruption or return, but Stream's forEach method does not directly support this method. This article will explain the reasons and explore alternative methods for implementing premature termination in Stream processing systems. Further reading: Java Stream API improvements Understand Stream forEach The forEach method is a terminal operation that performs one operation on each element in the Stream. Its design intention is

TimeStamp to Date in Java TimeStamp to Date in Java Aug 30, 2024 pm 04:28 PM

Guide to TimeStamp to Date in Java. Here we also discuss the introduction and how to convert timestamp to date in java along with examples.

Java Program to Find the Volume of Capsule Java Program to Find the Volume of Capsule Feb 07, 2025 am 11:37 AM

Capsules are three-dimensional geometric figures, composed of a cylinder and a hemisphere at both ends. The volume of the capsule can be calculated by adding the volume of the cylinder and the volume of the hemisphere at both ends. This tutorial will discuss how to calculate the volume of a given capsule in Java using different methods. Capsule volume formula The formula for capsule volume is as follows: Capsule volume = Cylindrical volume Volume Two hemisphere volume in, r: The radius of the hemisphere. h: The height of the cylinder (excluding the hemisphere). Example 1 enter Radius = 5 units Height = 10 units Output Volume = 1570.8 cubic units explain Calculate volume using formula: Volume = π × r2 × h (4

See all articles