• 反射


    一、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     }
  • 相关阅读:
    日常工作不常用内容记录:
    python接口自动化(四)——试着实现以下主程序
    python接口自动化(三)——从excel中获取数据
    redis工具类
    Airtest新年“首更”,1.1.7版本抢先看!
    AirtestIDE有哪些好用但是非常隐蔽的小功能?
    年终力荐:网易一站式的自动化测试解决方案
    This和Prototype定义方法的区别
    新版 IDEA 发布,牛逼!网友:内存占用有所好转!
    where 1=1 是什么鬼?
  • 原文地址:https://www.cnblogs.com/yanghaoyu0624/p/11776350.html
Copyright © 2020-2023  润新知