java学习篇:反射机制学习使用详解

一、什么是反射:
(1)Java反射机制的核心是在程序运行时动态加载类并获取类的详细信息,从而操作类或对象的属性和方法。本质是JVM得到class对象之后,再通过class对象进行反编译,从而获取对象的各种信息。
(2)Java属于先编译再运行的语言,程序中对象的类型在编译期就确定下来了,而当程序在运行时可能需要动态加载某些类,这些类因为之前用不到,所以没有被加载到JVM。通过反射,可以在运行时动态地创建对象并调用其属性,不需要提前在编译期知道运行的对象是谁。
三、反射的优缺点:
1、优点:在运行时获得类的各种内容,进行反编译,对于Java这种先编译再运行的语言,能够让我们很方便的创建灵活的代码,这些代码可以在运行时装配,无需在组件之间进行源代码的链接,更加容易实现面向对象。
2、缺点:
(1)反射会消耗一定的系统资源,因此,如果不需要动态地创建一个对象,那么就不需要用反射;
(2)反射调用方法时可以忽略权限检查,因此可能会破坏封装性而导致安全问题。
5.获取Class类对象的三种方式:一般用第三种
(1)方法一:
//方法1:对象.getClass()
Student stu=new Student();
Class clazz=stu.getClass();
(2)方法二:
//方法2:类.class
Class clazz= Student.class;
Class clazz=String.class;
方法三:
//方法3:Class.forName()
clazz=Class.forName(“java.lang.String”);
clazz=Class.forName(“java.util.Date”);
以下案例((示例均已上述Student类为基础):

package com.ptx.ad.controller.test;

/**
 * @Author: dev_guo
 * @Date: 2021/12/14 10:02
 */
public class Student {
    private String name;
    private int age;
    private double score;

    public Student() {
    }

    public Student(String name, int age, double score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public double getScore() {
        return score;
    }

    public void setScore(double score) {
        this.score = score;
    }

    public void learn() {
        System.out.println(this.name + "正在学习...");
    }

    @Override
    public String toString() {
        return "Student [name=" + name + ", age=" + age + ", score=" + score
                + "]";
    }
}

1.获取Class类对象测试类:

package com.ptx.ad.controller.test;

import java.lang.reflect.Modifier;

/**
 * @Author: dev_guo
 * @Date: 2021/12/14 10:05
 */
public class ClassDemo {
    public static void main(String[] args) {
        Student stu = new Student();
        Class<?> c1 = stu.getClass();//方式一
        Class<Student> c2 = Student.class;//方式二
        Class<?> c3 = null;
        try {
            c3 = Class.forName("com.ptx.ad.controller.test.Student");   // 方式三
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        System.out.println("方式一获取的Class对象为:" + c1.getSimpleName());
        System.out.println("方式二获取的Class对象为:" + c2);
        System.out.println("方式三获取的Class对象为:" + c3);
        int mod = c1.getModifiers();//获取修饰符所对应的整数
        String modifier = Modifier.toString(mod);//获取修饰符
        System.out.println(c1 + "类所用的修饰符为:" + modifier);
    }
    //运行结果:
    //方式一获取Class类对象:Student
    //方式二获取Class类对象:reflect.Student
    //方式三获取Class类对象:reflect.Student
    //Student类的修饰符:public
}

2.获取Filed对象


import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

/**
 * @Author: dev_guo
 * @Date: 2021/12/14 10:15
 */
public class FiledDemo {

    public static void main(String[] args) {
        Class<Student> cl = Student.class;//获取代表Student类的Class对象
        Field[] fields = cl.getDeclaredFields();//获取属性对象,返回数组
        System.out.println(cl.getSimpleName() + "类中声明的属性有:");
        for (Field f : fields) {
            String filedName = f.getName();//获取属性名
            Class<?> filedType = f.getType();//获取属性类型
            int mod = f.getModifiers();//获取修饰符对应整数
            String modifier = Modifier.toString(mod);//获取修饰符
            System.out.println(modifier + " " + filedType.getSimpleName() + " " + filedName);
        }

    }
    //运行结果:
    //Student类中声明的属性有:
    //private String name
    //private int age
    //private double score
}

3.获取Method对象:

package com.ptx.ad.controller.test;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
/**
 * @Author: dev_guo
 * @Date: 2021/12/14 10:19
 */
public class MethodDemo {
    public static void main(String[] args) {
        try {
            Class<?> cls=Class.forName("com.ptx.ad.controller.test.Student");
            Method[] methods=cls.getDeclaredMethods();
            for(Method method:methods){
                String methodName=method.getName();   // 获取方法名称
                Class<?> returnType=method.getReturnType();  // 获取方法的返回值类型
                String modStr= Modifier.toString(method.getModifiers());   // 获取方法的修饰符
                Class<?>[] paramTypes=method.getParameterTypes();   // 获取参数类型
                System.out.print(modStr+" "+returnType.getSimpleName()+" "+methodName+"(");
                if(paramTypes.length==0){
                    System.out.print(")");
                }
                for(int i=0;i<paramTypes.length;i++){   // 遍历形式参数类型
                    if(i==paramTypes.length-1){
                        System.out.print(paramTypes[i].getSimpleName()+" args"+i+")");
                    }else{
                        System.out.print(paramTypes[i].getSimpleName()+" args"+i+",");
                    }
                }
                System.out.println();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //运行结果:
    //public void eat(String args0,String args1)
    //public int getAge()
    //public void setAge(int args0)
    //public double getScore()
    //public void setScore(double args0)
}

4.获取Constructor对象:

package com.ptx.ad.controller.test;

import java.lang.reflect.Constructor;

/**
 * @Author: dev_guo
 * @Date: 2021/12/14 10:30
 */
public class ConstructorDemo {

    public static void main(String[] args) {
        Class<Student> cl = Student.class;//获取Class对象,代表Student类
        try {
            Constructor<Student> con = cl.getDeclaredConstructor(String.class, int.class, double.class);//获取散参构造方法
            Student stu = con.newInstance("张无忌", 23, 96.7);
            System.out.println(stu);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
    //运行结果: Student [name=张无忌, age=23, score=96.7]
}

5.动态创建方法:

package com.ptx.ad.controller.test;

import java.lang.reflect.Method;

/**
 * @Author: dev_guo
 * @Date: 2021/12/14 10:51
 */
public class InvokeMethod {
    public static void main(String[] args) {
        Class<Student> cls = Student.class;
        try {
            Student stu = cls.newInstance();   // 通过反射机制实例化对象,使用此newInstance()方法,要求类中必须包含一个无参构造方法
            Method setNameMethod = cls.getMethod("setName", String.class);
            setNameMethod.invoke(stu, "风清扬");   // 使用stu对象调用setName(String name)方法,传入"风清扬"参数
            Method getNameMethod = cls.getMethod("getName");
            System.out.println(getNameMethod.invoke(stu));  // 使用stu对象调用getName()方法,返回一个值
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //运行结果: 风清扬
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值