反射学习代码

package com.wuya.reflection;

//用于测试反射需要准备的物料类
public class Student {
    String name;
    public int age;
    private String addr;

    public Student() {
    }

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

    public Student(String name,int age,String addr) {
        super();
        this.name = name;
        this.age = age;
        this.addr = addr;
    }

    public void tell() {
        System.out.println("tell()......");
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", addr='" + addr + '\'' +
                '}';
    }
}
package com.wuya.reflection;

import org.junit.Test;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
//测试 反射
public class Test1Reflect {
    //1.通过单元测试获取类的字节码对象(类对象)
    @Test
    public void getClazz() throws ClassNotFoundException {
        //1.1 获取Student类的字节码对象
        Class<?> vs1 = Class.forName("com.wuya.reflection.Student");
        Class<Student> vs2 = Student.class;
        Class<? extends Student> vs = new Student().getClass();
        //1.2调用方法
        System.out.println(vs);//class com.wuya.reflection.Student 反射得到类的字节码Class对象
        System.out.println(vs.getName());    //com.wuya.reflection.Student 获取类的全路径名
        System.out.println(vs.getTypeName());//com.wuya.reflection.Student
        System.out.println(vs.getSimpleName()); //Student 获取类名
        System.out.println(vs.getPackage().getName());//com.wuya.reflection 获取包名
        System.out.println(Arrays.toString(vs.getAnnotations()));//[] TODO getAnnotations()的返回值是数组
        System.out.println(vs.getAnnotation(Annotation.class));//null TODO 终于会这个方法的传参了
    }
    //2.通过单元测试来获取构造方法
    @Test
    public void getConstructor() throws ClassNotFoundException, NoSuchMethodException {
        Class<?> clazz = Class.forName("com.wuya.reflection.Student");
        System.out.println(clazz.getConstructor(String.class,int.class));
        //下面这行虽然也是获取构造方法们,但是它是字符串,只是能看一下,不能进一步操作;要操作还需进行遍历/循环
        System.out.println(Arrays.toString(clazz.getConstructors()));//TODO getConstructors()的返回值是数组
        //获取所以公开的构造方法们
        Constructor<?>[] cs = clazz.getConstructors();
        for (Constructor<?> c : cs) {
            System.out.println(c.getName());//获取当前构造的名字
            Class[] cps = c.getParameterTypes();//获取构造函数中的参数类型们
            System.out.println(Arrays.toString(cps));
        }
    }
    //3.获取成员方法
    @Test
    public void getMethod() throws NoSuchMethodException {
        Class<Student> clazz = Student.class;
        System.out.println(clazz.getMethod("tell"));//获取某一个方法,注意传参
        Method[] ms = clazz.getMethods();
        for (Method m : ms) {
            System.out.println(m.getName());
            System.out.println(Arrays.toString(m.getParameterTypes()));
        }
    }
    //4.获取成员变量
    @Test
    public void getFields() throws NoSuchFieldException {
        Class<? extends Student> clazz = new Student().getClass();
        System.out.println(clazz.getField("age"));//TODO 必须是public修饰的变量才能获取到
        System.out.println(clazz.getDeclaredField("name"));//TODO 暴力反射就无所谓了
        Field[] fs = clazz.getDeclaredFields();//暴力反射
        for (Field f : fs) {
            System.out.println(f.getName());
            System.out.println(f.getType().getName());//获取变量的类型
        }
    }
    //5.反射创建对象
    @Test
    public void createObject() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        //5.1 获取类对象
        Class<Student> clazz = Student.class;
        //5.2 创建对象
        //5.2.1 TODO 触发无参构造
        Student s = clazz.newInstance();
        System.out.println(s);//Student{name='null', age=0, addr='null'}

        //5.2.2 TODO 根据方法的参数获取指定的构造方法
        //传入的参数不是参数的直接类型,而是对应类型的字节码对象,如下:
        //getConstructor(Class<?>... parameterTypes) 可见参数是"可变参数"--传入0个,1个...都行
        Constructor<Student> c = clazz.getConstructor(String.class,int.class,String.class);
        Student s2 = c.newInstance("张婕",56,"北京市中关村");
        System.out.println(s2);//Student{name='张婕', age=56, addr='北京市中关村'}

        //5.2.3 TODO 测试子类Student中的方法,用子类对象测;
        // 如果 s 或 s2 是Object对象(父类对象)时,需要强转为Student类型
        System.out.println(s2.age);//56
        System.out.println(s2.name);//张婕
        //System.out.println(s2.addr);//编译期报错,因为addr是私有属性
        s2.tell();//tell()......
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值