Java反射(手记)

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反射(手记))