通过反射来剖析类的构成

类的构成:
构造方法:Constructor
成员变量:Field
成员方法:Method

获取构造方法对象;


		//先获取到该类的字节码文件对象
        Class clazz = Class.forName("org.westos.demo2.Student");
        
        //getConstructors():获取该类中所有的构造方法对象,私有的除外
        Constructor[] constructors = clazz.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }
       
        
        //getDeclaredConstructors(); 获取所有的构造方法对象,包括私有的
        Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
        for (Constructor declaredConstructor : declaredConstructors) {
            System.out.println(declaredConstructor);
        }
      

        //获取空参的构造方法对象
        Constructor constructor = clazz.getConstructor();
        
        //获取一个参数的构造方法对象,传入参数的class类型,不能获取私有的
        Constructor constructor1 = clazz.getConstructor(String.class);
        
        //获取私有的构造方法对象getDeclaredConstructor(String.class, int.class);
        Constructor constructor2 = clazz.getDeclaredConstructor(String.class, int.class);
student类:
public class Student {
    public Student(){
        System.out.println("空参构造");
    }

    public Student(String name) {
        System.out.println("有参构造"+name);
    }

    private Student(String name,int age) {
        System.out.println("私有的有参构造" + name+"==="+age);
    }
}

同上的应用:
 		//获取该类的字节码文件对象
        Class aClass = Class.forName("org.westos.demo2.Student");

        //获取空参的构造方法对象
        Constructor constructor = aClass.getConstructor();

        //通过构造方法对象中的 newInstance() 来创建出该类的一个实例
        Student obj = (Student) constructor.newInstance();


        //通过有参构造来创建该类的实例
        Constructor constructor1 = aClass.getConstructor(String.class);
        Object o = constructor1.newInstance("张三");
        
        //通过私有的构造创建该类的对象
        Constructor declaredConstructor = aClass.getDeclaredConstructor(String.class, int.class);
        declaredConstructor.setAccessible(true); //取消语法检测
        Object o1 = declaredConstructor.newInstance("王五", 25);

获取类的字段对象:


		//获取该类的字节码文件对象
        Class aClass = Student.class;

        //获取类中的所有的字段对象
        Field[] fields = aClass.getFields();
        for (Field field : fields) {
            System.out.println(field);
        }

        //getDeclaredFields() 获取类中所有的字段对象,包括私有
        Field[] declaredFields = aClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }

        //获取单个的字段
        Field name = aClass.getField("name");

        //获取私有的字段对象
        Field sex = aClass.getDeclaredField("sex");



student类:
public class Student {
    public String name;
    public int age;
    private char sex;
}

同上的应用:
		//获取字节码文件对象
Class<?> aClass = Class.forName("org.westos.demo3.Student");
        
        Field field = aClass.getField("name");
        Object obj = aClass.getConstructor().newInstance();
        

        //给字段设置值
        field.set(obj,"张三");
        
        //获取字段的值
        Object o = field.get(obj);


        //给私有字段设置值
        Field sex = aClass.getDeclaredField("sex");
        //对于私有可以取消语法检测
        sex.setAccessible(true); 
        sex.set(obj,'男');
        Object o1 = sex.get(obj);
        Character character= (Character) o1;

获取方法对象:

	 Class<?> aClass = Class.forName("org.westos.demo4.Student");
        //获取所有的方法对象,包括父类的方法对象,私有除外
        Method[] methods = aClass.getMethods();
        for (Method method : methods) {
            System.out.println(method.getName());
        }
        
        //获取该类的所有方法对象,包括私有的方法
        Method[] declaredMethods = aClass.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }

        
        //获取单个的方法对象,参数1,方法名;参数2:这个方法上的参数的字节码类型
        Method hehe = aClass.getMethod("hehe");
        System.out.println(hehe);
        Method haha = aClass.getMethod("haha", String.class);
        System.out.println(haha);
        Method test = aClass.getMethod("test", String.class,int.class);
        System.out.println(test);

        //获取私有的方法对象
        Method method = aClass.getDeclaredMethod("method", String.class, int.class);
        System.out.println(method);
public class Student {
    public void test(){
        System.out.println("这是一个空参方法");
    }

    public int test(String name) {
        System.out.println("这是一个参数方法");
        return 100;
    }

    public int test(String name,int a) {
        System.out.println("这是两个参数的方法");
        return 100+a;
    }

    private int method(String name, int a) {
        System.out.println("这是一个私有的方法");
        return 100 + a;
    }
}

应用:
 		//通过反射机制,调用类中的方法执行

        Class<?> aClass = Class.forName("org.westos.demo4.Student");

        //获取该方法的对象
        Method test = aClass.getMethod("test");
        Object obj = aClass.getConstructor().newInstance();

        //通过方法对象中的 invoke() 让这个方法执行
        test.invoke(obj);



        Method haha = aClass.getMethod("test", String.class);
        //让一个参数的方法 执行 也可以拿到该方法的返回值
        Object o1 = haha.invoke(obj, "王五");

        //让两个参数的方法执行
        Method test1 = aClass.getMethod("test", String.class, int.class);
        Object o2 = test1.invoke(obj, "张三", 23);

        //让私有的方法执行
        Method method = aClass.getDeclaredMethod("method", String.class, int.class);
        method.setAccessible(true);//取消语法检测
        Object value = method.invoke(obj, "李四", 24);

应用实例:

		 //基于狗类开发
      
        
        Properties properties = new Properties();
        
        //从配置文件中读取全限定名和方法名,易于修改,方便维护;
        properties.load(new FileInputStream("peizhi.properties"));
        
        //属性集合读取指定键对应的类名;
        String className = properties.getProperty("className");
        //获取类字节码文件对象;
        Class<?> aClass = Class.forName(className);
        
       
        //如果你使用空参构造来创建对象
        //Class对象里面newInstance()这个方法,可以创建该类的对象
        Object o1 = aClass.newInstance();
        Method methodName = aClass.getDeclaredMethod(properties.getProperty("methodName"));
        methodName.invoke(o1);

狗类:
public class Dog {
    public void eat(){
        System.out.println("狗吃骨头");
    }

    public void sleep() {
        System.out.println("狗睡觉");
    }
}

下图是配置文件内容:

在这里插入图片描述

另外,泛型只在编译器有效,运行期就自动擦除了,应用如下:

//ArrayList<Integer> 想在这个集合中添加一个字符串数据,如何实现呢?
ArrayList<Integer> integers = new ArrayList<>();
        integers.add(100);
        //越过泛型检测,只能在运行期,反射在运行期的一种机制

        Class<? extends ArrayList> aClass = integers.getClass(); //ArrayList.class
        Method add = aClass.getDeclaredMethod("add", Object.class);

        add.invoke(integers,"abc");
        System.out.println(integers);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值