• 反射详解


    反射

    反射:是底层技术 (开发工具和框架,使代码更通用)

    java.lang.reflect//反射包

    1).类对象Class

    是类加载的产物,封装了一个类的所有信息(类名,父类,接口,属性,方法,构造方法…)

    类加载: 当JVM第一次使用一个类的时候,需要读取这个类对应的字节码文件,获取类的信息并保存起来

    类对象: 记录类的信息的对象. 类加载后,将类的信息封装成类对象,保存在方法区中

    获得类对象的三种方法:

    Class c1 = HashMap.class; //获取类对

    Object o = new HashMap();

    ​ Class c2 = o.getClass();

    String className = “java.util.HashMap”; //写类的全名,带包

    ​ Class c3 = Class.forName(className); //Class.forName, 加载

    常用方法:

    getName() 获取全类名

    ​ getSimpleName() 获取简单类名,不含包名

    getSuperClass() 获取父类的类对象

    ​ getInterfaces() 获取所有实现了的接口类对象,返回Class[]

    ​ getField() 获取一个公开属性对象,

    ​ getDeclaredField() 获取一个属性,包括非公开的

    getFields() 获取所有的公开属性对象,包括继承自父类的属性

    ​ getDeclaredFields() 获取本类中所有的属性对象,

    ​ getMethod(“方法名”,参数表.class) 获取一个公开方法,注意参数表的位子

    ​ getDeclaredMethod(“方法名”,参数表.class)获取一个本类的方法,包括非公开的

    getMethods() 获取所有的公开方法,包括父类的

    ​ getDeclaredMethods() 获取本类所有的方法

    ​ getConstructors() 返回所有的构造方法的对象信息

    用法:例

    ​ Class c = HashMap.class;

    ​ System.out.println(c.getName()); //带包名,全名

    ​ System.out.println(c.getSimpleName()); //不带包名,简单名

    ​ System.out.println(c.getSuperclass().getName()); //父类的带包名

    Class[] cc = c.getInterfaces(); //获得实现的接口

    ​ for(int i = 0; i < cc.length; i++) { //遍历以实现的接口并打印名字

    ​ System.out.println(cc[i].getName());}

    2).Field

    Field****:封装一个类对象的所有属性信息

    ​ 常用方法:

    getFields();****返回类中所有的公开属性,包括父类中的属性,返回Field数组

    getDeclaredFields();****返回本类中所有属性,包括非公开属性,返回Field数组

    ​ 用法:

    ​ class Student { public String name; public int age;}

    ​ main();

    ​ Class c = Student.class;

    ​ Field[] f = c.getFields();

    ​ for(int i = 0; i < f.length; i++) {

    ​ System.out.println(f[i]);

    ​ }

    3).Method

    Method****:封装一个类对象的所有方法信息

    ​ 常用方法:

    getMethod(“方法名”, 此方法的参数表(例如Object.class));****返回类中的一个方法,

    getDeclaredMethod(“方法名”, 此方法的参数表(例如Object.class)); 获取的一个包括非公开的方法

    getMethods();****返回类中所有的公开方法,包括父类中的方法,返回Method数组

    getDeclaredMethods();****返回本类中所有方法,包括非公开方法,返回Method数组

    用法:

    Class c = HashMap.class;

    ​ Method m1 = c.getMethod(“put”);//返回无参put方法

    ​ m1 = c.getMethod(“put”, Object.class, Object.class);//返回有两个Object类型参数的put方法

    System.out.println(m1.getReturnType().getName());//打印该方法的返回值类型名称

    Method[] m2 = c.getMethods(); //返回类对象c内的所有公开方法,包括父类的方法

    ​ for(int i = 0; i < m2.length; i++) {

    ​ System.out.println(m2[i].getName());

    ​ }

    Method[] m3 = c.getMethods(); //返回类对象c内的所有非公开方法

    ​ for(int i = 0; i < m3.length; i++) {

    ​ System.out.println(m3[i].getName());

    ​ }

    3).Constructor

    Constructor****:封装一个类对象所有构造方法信息

    ​ 常用方法:

    getConstructos();****返回类中所有的构造方法,包括父类中的方法,返回Constructor数组

    ​ 用法:

    ​ Class c = Student.class;

    ​ Constructor[] ct = c.getConstructors(); //获取所有构造方法

    ​ System.out.println(ct[0].getName());

    4).利用反射处理类的对象(实例化对象、调用方法)

    动态对类做操作:

    ​ ①对Class对象调用newInstance(),可以创建该类的对象调用无参构造方法

    ​ Class c = Class.forName(“com.baizhi.Student”); //注意抛异常

    ​ c.newInstance();

    ​ ②对Method对象调用invoke(Object o),对o调用方法

    ​ Method m = 对象.getMethod(“方法名”,参数类型.class);

    ​ m.invoke(o);

    ​ ③可以调用私有方法,但必须先将方法的可访问性属性改为true(setAccessible(true))

    ​ Method m = 对象.getDeclaredMethod(“方法名”,参数类型.class);//私有方法

    ​ m.setAccessible(true); //修改可访问性

    ​ m.invoke(o);

    ​ ④访问并设置对象的属性

    用法:

    ​ class Student {

    ​ public void study() { System.out.pritln(“在学习”);}

    ​ public String study(String course) { return “学习课程:” + course; }

    }

    main():

    ​ //Student o = new Student();

    ​ Class c = Class.forName(“包.Student”);//加载类Student

    ​ Object o = c.newInstance();//创建类的对象

    //o.study();调用无参方法

    ​ Method m1 = c.getDeclaredMethod(“study”); //获取无参的study方法

    ​ m1.invoke(o); //调用方法

    //o.study();调用有参方法

    ​ Method m2 = c.getDeclaredMethod(“study”, String.class); //获取方法

    ​ Object result = m2.invoke(o, “CoreJava”); //调用有参构造,并将返回值赋给o

    ​ System.out.println(result);

  • 相关阅读:
    (转)JQuery中$.ajax()方法参数详解
    __dopostback的用法 . 编辑
    (转)__dopostback的用法 .
    (转)如何区分一个程序员是“老手“还是“新手“?
    jQuery验证框架 .
    location.href的用法
    为用户设置密码
    设置环境变量
    用 xampp 在ubuntu 下配置php 运行环境 lampp
    安装与配置JDK
  • 原文地址:https://www.cnblogs.com/linanana/p/12107338.html
Copyright © 2020-2023  润新知