反射

一、Class类 字节码文件类
  获取字节码对象的三种方式:
    1、类名 变量 = new 类名();
     Class c = 变量.getClass();
    2、Class c = 类名.class;
    3、Class c = Class.forName("全路径的类名加包名");
二、获取字节码文件

  需要反射的类:

 1 public class Student {
 2     private String name;
 3     public int age;
 4     static {
 5         System.out.println("Student类进内存了");
 6     } 
 7      
 8     public Student() { 
 9         super();
10     }
11     public Student(String name,int age) {
12         System.out.println("公共有参构造");
13     }
14     private Student(String name) {
15         System.out.println("私有有参构造");
16     }
17     
18     
19     public void eat() {
20         System.out.println("公共无参方法");
21     }
22     public void sleep(String name) {
23         System.out.println("公共有参方法");
24     }
25     
26     public void sleep(String name,int age) {
27         System.out.println("公共有参方法");
28     }
29     private void get(int age) {
30         System.out.println("私有有参方法");
31     }
32     @Override
33     public String toString() {
34         return "Student [name=" + name + ", age=" + age + "]";
35     }
36     
37 }

 


  1、方法:
    getConstructors():获取public 修饰的构造方法
    getDeclaredConstructors():获取所有的构造方法
    以上返回 Constructor[] 数组
    getConstructor(Class<?>... parameterTypes):获取指定参数的public 修饰的构造方法
    getDeclaredConstructor(Class<?>... parameterTypes):获取指定参数的 构造方法,包括私有
    以上返回 Constructor 对象
  2、通过构造方法创建对象
     a(public):

 1 public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException,
 2             InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
 3 //        获取字节码文件
 4         Class c = Class.forName("com.oracle.demo02.Student");
 5 //        获取指定参数的构造方法,无参数的不用写参数
 6         Constructor con = c.getDeclaredConstructor(String.class, int.class);
 7 //        使用该构造方法创建对象
 8         Object obj = con.newInstance("小明", 20);
 9         Student student = null;
10 //        向下转型
11         if (obj instanceof Student && obj != null) {
12             student = (Student) obj;
13         }
14         System.out.println(student);
15     }

     b(所有的):

 1 public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException,
 2             InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
 3 //        获取字节码文件
 4         Class c = Class.forName("com.oracle.demo02.Student");
 5 //        获取指定参数的构造方法
 6         Constructor declaredConstructor = c.getDeclaredConstructor(String.class);
 7 //        当反射私有的构造方法时需要暴力反射
 8         declaredConstructor.setAccessible(true);
 9 //        创建对象
10         Object obj = declaredConstructor.newInstance("小红");
11         Student stu = null;
12 //        向下转型
13         if (obj instanceof Student && obj != null) {
14             stu = (Student)obj;
15         }
16         System.out.println(stu);
17     }


    3、通过反射获取成员变量
      方法:
        getFields():获取所有用public 修饰的变量
        getDeclaredFields():获取所有的 变量(包括私有)
        以上放回 Field[] 数组:
        getField(String name):获取指定的public 修饰的变量
        getDeclaredField(String name):获取指定变量,包括私有

      获取和赋值:
        a(public):

 1 public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException {
 2 //        获取字节码文件对象
 3         Class c = Class.forName("com.oracle.demo02.Student");
 4 //        获取构造方法
 5         Constructor constructor = c.getConstructor();
 6 //        创建对象,赋值时使用
 7         Object obj = constructor.newInstance();
 8         Student stu = null;
 9 //        向下转型
10         if (obj instanceof Student && obj != null) {
11             stu = (Student)obj;
12         }
13         Field field = c.getField("age");
14 //        设置值
15         field.set(stu, 20);
16 //        取值
17         System.out.println(field.get(stu));
18     }

        b(所有的):

 1 public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException {
 2 //        获取字节码文件对象
 3         Class c = Class.forName("com.oracle.demo02.Student");
 4 //        获取构造方法
 5         Constructor constructor = c.getConstructor();
 6 //        创建对象,赋值时使用
 7         Object obj = constructor.newInstance();
 8         Student stu = null;
 9 //        向下转型
10         if (obj instanceof Student && obj != null) {
11             stu = (Student)obj;
12         }
13         
14         Field field = c.getDeclaredField("name");
15 //        暴力反射,取消 field 属性对象 的Java 语言检查访问检查
16         field.setAccessible(true);
17 //        设置值
18         field.set(stu, "小红");
19 //        取值
20         System.out.println(field.get(stu));
21     }

    

    4、通过反射调用方法:
      方法:
        getMethods():获取public 修饰的所有方法
        getDeclaredMethods():获取所有方法,包括私有的
        以上返回 Method[] 数组
        getMethod(String name, Class<?>... parameterTypes):获取指定方法名和指定参数的方法 并 用 public 修饰的方法
        getDeclaredMethod(String name, Class<?>... parameterTypes):获取 指定 方法名和指定参数 的 所有方法,包括私有
      获取并调用:
        a(public):

 1 public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
 2 //        获取字节码文件
 3         Class c = Class.forName("com.oracle.demo02.Student");
 4 //        创建对象
 5         Object obj = c.newInstance();
 6 //        获取指定方法,当没有参数是,第二个参数不写
 7         Method method = c.getMethod("sleep", String.class);
 8 //        执行
 9         method.invoke(obj, "睡觉");
10     }

 


        b(所有的):

 1 public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
 2 //        获取字节码文件
 3         Class c = Class.forName("com.oracle.demo02.Student");
 4 //        创建对象
 5         Object obj = c.newInstance();
 6 //        获取指定方法
 7         Method declaredMethod = c.getDeclaredMethod("get", int.class);
 8 //        暴力反射
 9         declaredMethod.setAccessible(true);
10 //        调用
11         declaredMethod.invoke(obj, 16);
12     } 

    5、泛型擦除:

 1 public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
 2         ArrayList<Integer> list = new ArrayList<Integer>();
 3         list.add(3);
 4         list.add(5);
 5 //        获取 ArrayList 的字节码文件
 6         Class c = list.getClass();
 7 //        获取add方法
 8         Method method = c.getMethod("add", Object.class);
 9 //        传入的对象是需要被擦除的list集合,并执行
10         method.invoke(list, "小红");
11 //        注意接收的使用用 Object 接收,如果需要操作,再向下转型成对应的类
12         Object str = list.get(2);
13         System.out.println(str);
14     }

 

posted @ 2019-11-01 12:52  养一只Tom猫  阅读(152)  评论(0编辑  收藏  举报