美文网首页
Java反射(手记)

Java反射(手记)

作者: 撸码的皮大叔 | 来源:发表于2019-04-17 21:53 被阅读0次

    1. 概念

    定义:反射主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。在计算机科学领域,反射是一类应用,它们能够自描述和自控制。这类应用通过某种机制来实现对自己行为的描述和检测,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。

    做一些做不了的事情 一些不正规的手段 。 所有的功能都是基于我们的字节码(class) 一个类的class在内存中应该只有一份 而且class 其实也是一个对象

    2.实例化对象

    2.1实例化一个无参的构造方法
    • class.newInstance(); 实例化一个无参的构造方法

    代码示例:
    写一个测试的 TestBean.class

     public class TestBean { 
    
     private String name = "LorenzoGao";
     private TestBean() {
    
        }
    
    public void sysName() {
           System.out.print(name);
        }
    }
    
    //使用反射
     try {
                TestBean testBean=TestBean.class.newInstance();
                testBean.sysName();
            }catch (Exception e) {
                e.printStackTrace();
            }
    
    2.2实例一个有参数的构造方法
    • getConstructor(Class<?>... parameterTypes) 参数是你构造方法的参数的类型

    只返回制定参数类型访问权限是public的构造器

    • getDeclaredConstructor (Class<?>... parameterTypes) 参数是你构造方法的参数的类型

    这个方法会返回制定参数类型的所有构造器,包括public的和非public的,当然也包括private的

    public class TestBean{
     
        private String name = "LorenzoGao";
    
        private TestBean(String name) {
            this.name = name;
        }
    
    
        public void sysName() {
          System.out.print(name);
        }
    
    
    }
    
    
    //使用反射
    
     try {
                Constructor constructor = TestBean.class.getDeclaredConstructor(String.class);
                constructor.setAccessible(true);
                TestBean bean = (TestBean) constructor.newInstance("Hello");//调用构造方法传的参数,前提是不是用private修饰 等同于new TestBean("Hello") 
                bean.sysName();
            } catch (Exception e) {
                e.printStackTrace();
            }
    
    
    2.3 实例化一个连XXX.class都拿不到的构造方法 ,如ActivityThread.class
     try {
                Class clazz = Class.forName("android.app.ActivityThread");
                Field field = clazz.getDeclaredField("sCurrentActivityThread");
                field.setAccessible(true);
                Object object =field.get(null); //static 修饰 跟对象是没关系 ,跟类是有关系 所以可以传个null
                System.out.print(object.toString());
    
    
            } catch (Exception e) {
                e.printStackTrace();
            }
    

    3.方法调用

    • getDeclaredMethod(String name, Class<?>... parameterTypes) ,

    获得对象所声明的public的和非public的,当然也包括private的

    • getDeclaredMethods()

    返回所有的方法,包括public的和非public的,当然也包括private的

    • getMethod(String name, Class<?>... parameterTypes)

    获得对象所声明的public方法

    • getMethods()

    返回所有是public的方法

    • invoke(Object obj, Object... args)

    执行方法 obj表示执行者,args表示传入方法参数,无参方法,可不传。

    name 表示方法名,parameterTypes 表示的有参方法的参数类型

    3.1获取一个无参方法
    public class TestBean {
    
        private String name = "LorenzoGao";
    
        public TestBean(String name) {
            this.name = name;
        }
    
    
        private  void sysName() {
          System.out.print(name);
        }
    
    }
    
    
             //反射获取方法
              try {
    
                TestBean bean=new TestBean("Hello");
                Method method = TestBean.class.getDeclaredMethod("sysName");
                method.setAccessible(true);
                method.invoke(bean); //表示bean去执行这个方法
    
            } catch (Exception e) {
                e.printStackTrace();
            }
    
    
    3.2获取一个有参方法
    public class TestBean {
    
        private String name = "LorenzoGao";
    
        public TestBean(String name) {
            this.name = name;
        }
    
    
        private  void sysName() {
          System.out.print(name);
        }
        private  void sysName(String params) {
            System.out.print(params);
        }
    
    }
    
    
    //反射
      try {
                TestBean bean=new TestBean("Hello");
                Method method =TestBean.class.getDeclaredMethod("sysName",String.class);
                method.setAccessible(true);
                method.invoke(bean,"哈哈哈");
    
            } catch (Exception e) {
                e.printStackTrace();
            }
    
    

    4.获取属性

    • getDeclaredField(String name)

    获取对象里面指定名字的public和private 修饰的属性

    • getDeclaredFields()

    获取对象里面所有public和private 修饰的属性

    • getField(String name)

    获取对象里面指定名字的public 修饰的属性

    • getFields()

    获取对象里面所有的public 修饰的属性

    name 表示属性名字

    public class TestBean {
    
        private String name = "LorenzoGao";
    
        public TestBean(String name) {
            this.name = name;
        }
    
    
        private  void sysName() {
          System.out.print(name);
        }
        private  void sysName(String params) {
            System.out.print(params);
        }
    
    }
    
    
     //反射获取属性
      try {
    
                TestBean testBean = new TestBean("123");
                Field field = TestBean.class.getDeclaredField("name");
                field.setAccessible(true);
                String name = (String) field.get(testBean);//获取值
                System.out.print(name);
    
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    

    总是对反射概念很模糊,写一篇手记来总结一下。

    相关文章

      网友评论

          本文标题:Java反射(手记)

          本文链接:https://www.haomeiwen.com/subject/xnjfdftx.html