反射及其应用

JAVA反射机制允许在运行时动态获取类的属性和方法,并能调用对象的任意方法。获取Class对象有三种方式:通过对象、类或字符串。反射可用于创建对象、访问构造方法和属性,以及调用方法。文章提供了一个示例,展示了如何通过反射创建对象、获取构造方法和属性,并调用方法。
摘要由CSDN通过智能技术生成

什么是反射

        JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制

        要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象

        总之,反射就是把java类中的各种成分映射成一个个的Java对象。例如:一个类有:成员变量、方法、构造方法、包等等信息,利用反射技术可以对一个类进行解剖,把个个组成部分映射成一个个对象

反射的应用

1.获取class对象

要想使用反射,必须先获取到对应的Class类型的对象;所有的反射都指向一个类:java.lang.Class.这里有三种方式可以得到:

a.通过现有的对象来获取:

Class cls = master.getClass();//这里的master是一个现有的对象

b.通过现有的类来获取:

Class cls = Master.class;//Master是一个现有的能够拿到的类

c.通过字符串,来得到Class对象,这种方式是我们使用最广泛的一种方式,如Hibernate,mybatis的映射文件

Class cls = Class.forName("cn.sz.gl.pojo.Master");//双引号中是Master类的 包.类名

2.创建class对象

a.调用无参构造,来获得对象

Master master = (Master) cls.newInstance();//此时要求Master类中必须有无参构造可以调用

b.先获得指定的构造,然后利用这个构造方法,来获得对象

//得到指定的构造方法,如果有多个参数,中间用","隔开

Constructorcon = cls.getDeclaredConstructor(String.class,Integer.class);

Object obj = con.newInstance("abc",1);

注意:当没有无参构造,或者无参构造为private修饰的时候,我们不能够再使用newinstance的方式来实例化了。这时候,我们只能先获取指定构造,然后再来实例化

3.获取构造方法

//获得所有的构造方法,private修饰的构造不能获得
Constructor[] cons = cls.getConstructors();
for(int i=0;i<cons.length;i++){
	System.out.println(cons[i]);
}

也可以用来获取本类中的所有构造方法,包括private修饰的构造方法:

//获得本类所有的构造方法,包括private修饰的构造
Constructor[] cons = cls.getDeclaredConstructors();
for(int i=0;i<cons.length;i++){
    System.out.println(cons[i]);
}

还可以得到指定的某一个构造方法:

//得到指定的构造 方法,如果有多个参数,中间用","隔开
Constructor con =  cls.getDeclaredConstructor(String.class,Integer.class);
//也可以使用另一种方式来获得:cls.getConstructor(parameterTypes)
package com.fs.myreflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 通过反射 获取Student类信息,并调用方法,创建对象, 给属性赋值
 */
public class TestClass2 {
    public static void main(String[] args) throws IllegalAccessException, InvocationTargetException, InstantiationException {
        //1.得到Student类的Class对象
        Class<Student> clazz = Student.class;

        //2.得到属性 getFields() 得到公开的属性
       // System.out.println(clazz.getFields().length);

        //获取所有属性
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            System.out.println("属性名:"+field.getName()+",数据类型:"+field.getType());
        }

        //获取构造方法
        Constructor<?>[] declaredConstructors =clazz.getDeclaredConstructors();
        for (Constructor<?> constructor : declaredConstructors) {
             if(constructor.getParameterCount() == 3){ //使用三个参数的构造方法
                 Class<?>[] parameterTypes = constructor.getParameterTypes();
                 for (Class<?> parameterType : parameterTypes) {
                     System.out.println("参数的类型"+parameterType);
                 }
                 //调用构造方法创建对象
                 Student stu = (Student)constructor.newInstance("zhangsan", 21, "男");
                 System.out.println(stu);
             }

             //得到方法 getDeclaredMethods() 不包括继承的方法
            Method[] declaredMethods = clazz.getDeclaredMethods();
            for (Method method : declaredMethods) {
                System.out.println("方法名:"+method.getName()+"返回值类型:"+method.getReturnType()
                        +",参数个数:"+method.getParameterCount());
            }

            //Class类有一个创建对象方法  newInstance() 底层调用无参构造方法
            Student student = clazz.newInstance();


            //获取指定方法名,指定参数类型的方法
            try {
                Method studyMethod = clazz.getDeclaredMethod("study");
                //执行方法  invoke(对象,参数值)
                //默认是无法调用private的
                //设置允许访问
                studyMethod.setAccessible(true);
                studyMethod.invoke(student);

                //获取属性 设置属性值    获取属性值  对象.属性
                Field sex = clazz.getDeclaredField("sex");
                //允许访问
                sex.setAccessible(true);
                //给属性赋值 set()
                sex.set(student,"雄性");
                //获取属性的值 get()
                System.out.println(sex.get(student));


            } catch (NoSuchMethodException e) { //没有该方法的异常
                e.printStackTrace();
            } catch (NoSuchFieldException e) { //没有该属性的异常
                e.printStackTrace();
            }

        }




    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值