Java反射

反射:反射是Java语言的特征之一。
它允许在运行时动态加载类、获取类信息、生成对象、操作对象的属性或方法等。主要提供了以下功能:

  • 在运行时判断任意一个对象所属的类;
  • 在运行时构造任意一个类的对象;
  • 在运行时判断任意一个类所具有的成员变量和方法;
  • 在运行时调用任意一个对象的方法。甚至是private方法。
  • 生成动态代理。

正常执行:先将代码编写完毕  之后又JVM去进行运行  运行期间 无法对已有对象做内部设置 调用 访问等功能

反射中绕不开的类:Class<T>
    Class类表示 对 类类型的一种抽象 就是用来描述一个类对象
    任何一个类在底层都会对应一个Class类

类加载机制:
由一个Java文件 到 能够运行的对象之间 JVM都做了什么
类加载机制
文件 --编译-->  字节码文件 --类加载--> 进入JVM --连接--> 验证--准备--解析--初始化-->Class
 基本上所有的反射都是要通过Class对象来扩展的
 Java中 如何获取Class对象?
 三种方式:

  •  类名.class 的方式
  •  通过对象.getClass()方法
  •  通过Class.forName(String) 静态方法 String 为当前类的全限定名
public class Dog<T> {

    private String name = "Tom";
    public int age = 18;
    private boolean gender;
    public List<?>  t;

    private Dog(){
        System.out.println("DOG构造被调用");
    }

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

    public void play(String name){
        System.out.println(this.name+"开始和"+name+"一起玩耍");
    }

    private String show(){
        return "名字:"+name+",年龄:"+age;
    }

    @InitParam(name="狗子",age=4,gender=true)
    public void init(){
        System.out.println("名字:"+name+",年龄:"+age+",性别:"+gender);
    }
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface InitParam {
      String name() ;
      int age();
      boolean gender();
}
public class Demo {

    public static void main(String[] args) throws NoSuchFieldException {
//          demo1();
//        try {
            demo9();
       /* } catch (NoSuchMethodException | InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }*/
    }


    /*
    * 此处有误  只能获取  成员属性 方法泛型 返回值泛型
    * 不能获取类 接口 局部变量泛型
    * ParameterizedType
    * */
    public  static void demo9() throws NoSuchFieldException {
        Dog<Integer> d =  new Dog<>("Tom",3);
        Class<? extends Dog> dc = d.getClass();
        Field t = dc.getField("t");

        Type type = t.getGenericType();
        if(type instanceof  ParameterizedType){
            ParameterizedType pt = (ParameterizedType) type;
            Type[] at = pt.getActualTypeArguments();
            System.out.println(at[0].getTypeName());
        }
    }


    public  static void demo8()
            throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Class<Dog> dc = Dog.class;
        Constructor<Dog> cc = dc.getDeclaredConstructor();
        cc.setAccessible(true);
        Dog dog = cc.newInstance();
        Method init = dc.getMethod("init");
        //从方法对象上去获取该方法的注解
        InitParam ip = init.getAnnotation(InitParam.class);
        int age = ip.age();
        String name = ip.name();
        boolean gender = ip.gender();

        Field[] df = dc.getDeclaredFields();
        for(Field f :df){

            switch(f.getName()){
                case "name" : f.setAccessible(true);f.set(dog,name);break;
                case "age" : f.setAccessible(true);f.setInt(dog,age);break;
                case "gender" : f.setAccessible(true);f.setBoolean(dog,gender);break;
            }
        }
        init.invoke(dog);
    }


    public static void demo7()
            throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        /*
        * 通过反射的形式来调用方法
        * */
        Dog dog = new Dog("小数", 2);
        //通过Class对象获取到play方法指针
        Class<? extends Dog> dc = dog.getClass();
        Method play = dc.getMethod("play",String.class);//获取可访问方法
        play.invoke(dog, "天使");//dog.play("天使")
        Method show = dc.getDeclaredMethod("show");//获取所有方法
        show.setAccessible(true);
        Object obj = show.invoke(dog);
        String result = null;
        if(obj instanceof String){
            result = (String)obj;
        }
        System.out.println(obj);
    }


    public static void demo6() throws NoSuchFieldException, IllegalAccessException {
        /*
        * 通过反射来修改 相应的属性值  或者获取一些私有属性值
        * */
        Dog dog = new Dog("小白", 3);
        dog.play("小新");
        Class<? extends Dog> dc = dog.getClass();
        Field name = dc.getDeclaredField("name");//只能获取所有
        name.setAccessible(true);
        Field age = dc.getField("age");//只能获取能够访问到的
        int a = age.getInt(dog);
        //需要从某个对象中获取指定的属性值
        String nstr = (String)name.get(dog);
        System.out.println("姓名"+nstr+",年龄:"+a);
        name.set(dog,"小花");
        age.set(dog,5);
        dog.play("小明");
    }

    public static void demo5(){
        /*
        * 调用【私有】构造来创建对象
        * */
        try {
            Constructor<Dog> privateCs = Dog.class.getDeclaredConstructor();
            /*
            * 默认情况下 私有内容获取到但不可使用 没有访问权限
            * 获取Declared对象之后 需要设置其允许访问私有内容
            * */
            privateCs.setAccessible(true);//表示可以访问私有对象
            Dog dog = privateCs.newInstance();
            dog.play("阿强");
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    public  static void demo4(){
        /*
        * 通过反射创建 调用普通构造器 来创建对象
        * 该构造器含有参数 无法通过newInstance来创建
        * 可以通过Constructor对象来使用指定类的构造器
        * 所有反射创建对象都是通过newInstance来创建 区别就是参数
        * */
        Class<Dog> dc = Dog.class;
        //通过类对象来获取该类的构造器对象
        try {
            Constructor<Dog> cs = dc.getConstructor(String.class, int.class);
            System.out.println("构造器名称:"+cs.getName());
            System.out.println("访问修饰符(整形):"+cs.getModifiers());
            System.out.println("构造器的toString方法:"+cs);
            Dog dog = cs.newInstance("小黑", 5);
            dog.play("小白");
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    public static void demo3(){
        //获取Dog的class对象
        //1.通过类名.class
        Class<Dog> dogClass = Dog.class;
        //2.通过对象.getClass()方法
//        Dog dog = new Dog();
//        Class<? extends Dog> aClass = dog.getClass();
        //3.通过Class.forName(String) 静态方法 String 为当前类的全限定名
        try {
            Class<?> aClass1 = Class.forName("com.liqk.reflect.Dog");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }


    public  static void demo1(){
        /*
        * 正常使用类和对象
        * */
        Dog dog = new Dog("旺财", 3);
        dog.play("小明");
    }

    public  static void demo2(){
        /*
        * 使用反射来创建对象
        * */
        try {
           /*可以创建Dog对象 并没有使用new关键字
           * 通过Class对象的 newInstance() 方法 可以待用该对象的 无参构造器来创建对象
           * 所以需要对该类  创建出一个无参构造 或者不要创建任何构造 构造器必须是public
           * */
            Dog dog = Dog.class.newInstance();
            dog.play("小红");
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值