紫玉坏小子

导航

java 学习三

反射

  • 反射的基本概念

    • 什么是反射?(在程序运行过程中分析类的一种能力)

    • 反射能做什么?

      • 分析类

        • 加载并初始化一个类

        • 查看类的所有属性和方法

      • 查看并使用对象

        • 查看一个对象的所有属性和方法

        • 使用对象的任意属性和方法

      • 反射的应用场景

        • 构造通用的工具

        • 搭建具有高度灵活性和扩展性的系统框架

    • 类加载器(ClassLoader)

      • 负责将类的字节码文件(.class文件)加载到内存中,并生成对应的Class对象

    • Class对象

      • java.lang.Class类的对象,也叫字节码文件对象,每个Class对象对应一个字节码文件

    • 类的加载时机

      • 创建类的实例

        • Student stu = new Student()

      • 访问类的静态成员

        • Calendar.getInstance();

      • 初始化类的子类

        • Class User extends Person{}

        • User user = new User();//先加载父类

      • 反射方式创建类的class对象

        • Class clazz = Class.forName("类的正名")//正名 :包名+类名 列如:cn.it.demo.Student

  • 获取Class对象的三中方式

    public class Demo {
       //获取Class对象(字节码文件对象)的三种方式
    //   1.Object类的getClass()
    //     Class clazz = 对象名.getClass();
    //   2.类的静态属性
    //     Class clazz = 类名.class;
    //   3.Class类的静态方法
    //     Class clazz = Class.forName("类的正名")
       public static void main(String[] args) throws ClassNotFoundException {
           //方式一
           Student student = new Student();
           Class<? extends Student> clazz = student.getClass();
           //方法二
           Class<Student> clazz1 = Student.class;
           //方法三
           Class<?> clazz2 = Class.forName("cn.it.pack.Student");
           System.out.println(clazz.hashCode());
           System.out.println(clazz1.hashCode());
           System.out.println(clazz2.hashCode());
      }
    }
  • 反射方式获取构造方法并使用
    • Constructor<T> 对象

      构造器对象,属于java.base模块,java.lang.reflect包

    • 通过Class对象获取构造器对象

      • getConstructor(Class<?>... parameterTypes)

        返回一个Constructor对象,仅公共构造函数

        Class<?>... :可变参数,代表Class类型的数组

        ? :通配符,代表不确定的任意类型

      • getDeclaredConstructor(Class<?>... parameterTypes)

        返回一个Constructor对象,可获取私有构造函数

      • getConstructors()

        返回此类所有(不含私有)构造函数的数组

    • Constructor的常用方法

      • String getName()

        返回构造函数名

      • T newInstance(Object... initargs)

        使用此构造函数和指定参数创建并初始化对象

public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
     Class clazz = Class.forName("cn.it.pack.Student");
     //通过反射获取到公共的构造方法(无参)
       Constructor cons = clazz.getConstructor();
       System.out.println(cons);
       //通过反射获取到公共的构造方法(有参)
       Constructor cons1 = clazz.getConstructor(String.class);
       System.out.println(cons1);
       //通过反射获取到私有的构造方法
       Constructor cons2 = clazz.getDeclaredConstructor(int.class);
       System.out.println(cons2);
       //通过反射获取到所有的公共构造方法
       Constructor[] constructors = clazz.getConstructors();
       for(Constructor c: constructors){
           System.out.println(c);
      }
       //获取到通过反射获取的构造方法名称
       System.out.println(cons.getName());
       //创建对象实例
       Student  o = (Student) cons.newInstance();
       System.out.println(o);

  }
  • 反射方式获取成员方法并使用
  • Method对象

    方法对象,属于java.base模块,java.lang.reflect包

  • 通过Class对象获取方法

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

      返回一个Method对象,仅公共成员方法

      name:方法名

      parameterTypes:方法的参数列表

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

      返回一个Method对象,可获取私有成员方法

    • getMethods()

      返回此类所有(不含私有)方法的数组

    • Method的常用方法
      • String getName()

        返回方法名

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

        在指定对象上调用此方法,参数为args

 public static void main(String[] args) throws Exception {
     Class clazz = Class.forName("cn.it.pack.Student");
       Student o = (Student)clazz.newInstance();
       //反射获取到方法 公共方法
       Method method1 = clazz.getMethod("say");
       System.out.println(method1);
       //反射获取到方法 私有方法
       Method method2 = clazz.getDeclaredMethod("say1");
       System.out.println(method2);
       //获取到所有的方法 公共的
       Method[] method = clazz.getMethods();
       for (Method m : method){
           System.out.println(m);
      }
       //调用此方法
       method1.invoke(o);
       //开启暴力反射
       method2.setAccessible(true);
       method2.invoke(o);

  }
Field 对象
  • 域(属性、成员变量)对象,属于java.base模块,java.lang.reflect包

  • 通过Class对象获取属性

    • getField(string name)

      返回一个Field对象,仅公共属性

      name:属性名

    • getDeclareField(String name)

      返回一个Field对象,可获取私有属性

    • getDeclaredFields()

      返回此类所有(含私有)属性的数组

  • Field的常用方法

    • set(Object obj,Object value)

      设置obj对象的指定属性值为value

    • setAccessible(boolean flag)
      将此属性的可访问性设置为指定布尔值 (暴力反射) 将private 变成 public
public static void main(String[] args) throws Exception {
     Class clazz = Class.forName("cn.it.pack.Student");
       Student o = (Student)clazz.newInstance();
       Field name = clazz.getField("name");
       name.set(o, "hxz");
       System.out.println("----------------------------------");
       Field name1 = clazz.getDeclaredField("age");
       name1.setAccessible(true);
       name1.set(o,9);
       System.out.println(o.toString());

  }

 

posted on 2021-01-12 16:38  紫玉坏小子  阅读(43)  评论(0编辑  收藏  举报