反射机制入门

 


一、什么是反射机制?

  Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,

可以了解任意一个对象所属的类,

可以了解任意一个类的成员变量和方法,

可以调用任意一个对象的属性和方法。

这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键。

二、获取Class类型对象的三种方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public static void main(String[] args) {
    Class c1 = null;
    try {
        //第一种方式:Class.forName("完整类名");
        c1 = Class.forName("java.lang.String");
        Class c2 = Class.forName("java.util.Date");
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    //第二种方式:类名.class
    Class c3 = java.lang.String.class;
    /**
     * 第三种方式:
     *  先创建对象,拿到对象的引用
     *  调用对象的getClass方法拿到Class对象
     */
    String s = new String();
    Class c4 = s.getClass();
    System.out.println(c1 == c3);//true
    System.out.println(c3 == c4);//true,说明两个对象的内存地址是一样的
}

三、反射获取属性Filed

User类:

1
2
3
4
5
class User {
    private String name;
    private Integer age;
    private String sex;
}

反射获取User对象:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public static void main(String[] args) throws Exception {
    Class<?> demo = Class.forName("User");
    Object obj = demo.newInstance();
    // 获取这个对象
    Class<?> objClass = obj.getClass();
    // 获取到所有的属性
    Field[] fields = objClass.getDeclaredFields();
    for (Field field : fields) {
        // 获取修饰符
        int i = field.getModifiers();
        String modifier = Modifier.toString(i);
        // 获取属性类型
        Class<?> type = field.getType();
        String simpleName = type.getSimpleName();
        // 获取属性名
        String fieldName = field.getName();
        System.out.println(modifier + " " + simpleName + " " + fieldName);
    }
}

输出结果:

1
2
3
private String name
private Integer age
private String sex

设置类中某个具体属性的属性值:  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static void main(String[] args) throws Exception {
    Class user = Class.forName("User");
    // 获取这个属性
    Field name = user.getDeclaredField("name");
    Field age = user.getDeclaredField("age");
    // 获取要修改的对象
    Object obj = user.newInstance();
    // 开启属性的私有访问权限
    name.setAccessible(true);
    age.setAccessible(true);
    // 设置值
    name.set(obj, "lisi");
    age.set(obj, 24);
    // 打印
    System.out.println(name.get(obj));
    System.out.println(age.get(obj));
}

输出结果:

1
2
lisi
24

四、反射获取方法

测试类:

1
2
3
4
5
6
7
8
9
class MethodDemo {
    public void m1() {
 
    }
 
    public static int m2(int i) {
        return i;
    }
}

反射获取类中的方法:  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public static void main(String[] args) throws Exception {
    // 获取类
    Class<?> methodDemo = Class.forName("MethodDemo");
    // 获取到所有的方法
    Method[] methods = methodDemo.getDeclaredMethods();
    for (Method method : methods) {
        // 获取方法修饰符
        String modifier = Modifier.toString(method.getModifiers());
        System.out.print(modifier + " ");
        Class<?> returnType = method.getReturnType();
        // 获取方法返回值类型
        String returnTypeSimpleName = returnType.getSimpleName();
        System.out.print(returnTypeSimpleName + " ");
        // 获取方法的方法名
        String methodName = method.getName();
        System.out.print(methodName + " ( ) {\n}\n");
        // 获取方法的形参参数列表
        Class<?>[] parameterTypes = method.getParameterTypes();
        for (Class<?> parameterType : parameterTypes) {
            // 获取到的是每一个形参的类型
            String simpleName = parameterType.getSimpleName();
            System.out.println(simpleName);
        }
    }
}

结果:

反射获取某个类的某个特定方法: 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import java.lang.reflect.Method;
 
/**
 * @author zhangzhixi
 * @date 2021-5-5 9:35
 */
public class Test04_获取类的某个方法 {
    public static void main(String[] args) throws Exception {
        // 1.获取这个类
        Class<?> methodDemo = Class.forName("ObtainMethodDemo");
 
        // 2.要想通过反射执行方法,得先创建这个对象
        Object obj = methodDemo.newInstance();
 
        // 3.获取某个类的某个特定方法
        Method m2 = methodDemo.getMethod("m2", int.class);
        Method m1 = methodDemo.getMethod("m1", null);
 
        // 4.执行方法,传入参数
        m1.invoke(obj, null);
        Object invoke = m2.invoke(obj, 666);
        System.out.println("返回值是:" + invoke);
    }
}
 
class ObtainMethodDemo {
    public void m1() {
        System.out.println("m1方法执行==>hello");
    }
 
    public static int m2(int i) {
        return i;
    }
}

测试结果:

1
2
m1方法执行==>hello
返回值是:666

反射获取类的构造方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import java.lang.reflect.Constructor;
 
/**
 * @author zhangzhixi
 * @date 2021-5-5 9:49
 */
public class Test05_获取某个类的某个构造方法 {
    public static void main(String[] args) throws Exception {
        // 1.获取class对象
        Class<?> student = Class.forName("Student");
        // 2.获取特定的构造方法
        Constructor<?> constructor = student.getDeclaredConstructor(String.class, Integer.class);
        Constructor<?> studentConstructor = student.getConstructor();
        // 3.执行构造
        studentConstructor.newInstance();
        Object newInstance = constructor.newInstance("张三", 23);
        System.out.println(newInstance);
    }
}
 
class Student {
    private String name;
    private Integer age;
 
    public Student() {
        System.out.println("student的无参构造方法执行!");
    }
 
    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
 
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

测试结果:

1
2
student的无参构造方法执行!
Student{name='张三', age=23}

反射获取父类/父接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.lang.reflect.AnnotatedType;
 
/**
 * @author zhangzhixi
 * @date 2021-5-5 10:03
 */
public class Test06_获取类的父类_父接口 {
    public static void main(String[] args) throws Exception {
        Class<?> aClass = Class.forName("java.lang.String");
 
        // 获取父类
        Class<?> superclass = aClass.getSuperclass();
        System.out.println(superclass);
 
        System.out.println("===============");
        // 获取父接口
        Class<?>[] interfaces = aClass.getInterfaces();
        for (Class<?> anInterface : interfaces) {
            System.out.println(anInterface);
        }
    }
}

测试结果:

1
2
3
4
5
class java.lang.Object
===============
interface java.io.Serializable
interface java.lang.Comparable
interface java.lang.CharSequence

  

  

  

  

 

  

  

  

posted @   Java小白的搬砖路  阅读(94)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话

喜欢请打赏

扫描二维码打赏

支付宝打赏

点击右上角即可分享
微信分享提示