Java反射

1. 类的加载

  1. 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化。
    1. 加载
      1. 指将class文件读入内存,并为之创建一个Class对象。
      2. 任何类被使用时系统都会建立一个Class对象。
    2. 连接
      1. 验证 - 是否有正确的内部结构,并和其他类协调一致。
      2. 准备 - 负责为类的静态成员分配内存,并设置默认初始化值。
      3. 解析 - 将类的二进制数据中的符号引用替换为直接引用。
    3. 初始化

2. 类的初始化时机

  1. 创建类的实例
  2. 类的静态变量,或者为静态变量赋值
  3. 类的静态方法
  4. 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
  5. 初始化某个类的子类
  6. 直接使用java.exe命令来运行某个主类

3. 三种类的加载器

  1. 负责将.class文件加载到内存中,并为之生成对应的Class对象。
    1. Bootstrap ClassLoader 根类加载器
      1. 也被称为引导类加载器,负责Java核心类的加载
      2. 比如System, String等。在JDK中JRE的lib目录下rt.jar文件中
    2. Extension ClassLoader 扩展类加载器
      1. 负责JRE的扩展目录中jar包的加载。
      2. 在JDK中JRE的lib目录下ext目录
    3. System ClassLoader 系统类加载器
      1. 负责在JVM启动时加载来自java命令的class文件,以及classpath环境变量所指定的jar包和类路径。

4. 反射的概念及作用

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象。

5. class文件的产生过程

Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的。

6. 获取class文件对象的三种方式

  1. 通过Object类中的getObject()方法
    Test t = new Test();
    Class c = t.getClass();
    
  2. 通过 类名.class 获取到字节码文件对象(任意数据类型都具备一个class静态属性)
    Class c = Test.getClass();
    
  3. 通过Class类中的方法(将类名作为字符串传递给Class类中的静态方法forName)。
    Class c3 = Class.forName("com.ccblogs.reflect.Test");
    
  4. 三种方法的区别:
    1. 前两种你必须明确Person类型。
    2. 第三种是指定这种类型的字符串,按照配置文件加载。

7. 反射获取空参构造方法并运行

  1. ComboListTest.java文件

    import java.lang.reflect.Constructor;
    
    public class ComboListTest {
        @SuppressWarnings({ "rawtypes", "unchecked" })
        public static void main(String[] args) throws Exception {
            Class c = Class.forName("com.ccblogs.inflect.ComboList");
            // 获取class文件对象中所有公共的构造方法
            Constructor[] cons = c.getConstructors();
            for (Constructor con : cons) {
                System.out.println(con);
            }
            // 运行类中的空参构造方法
            Constructor con = c.getConstructor();
            Object obj = con.newInstance();
            System.out.println(obj);
        }
    }
    
  2. ComboList.java文件

    public class ComboList {
        public ComboList() {
            System.out.println("无参构造方法");
        }
        
        public ComboList(String str, int iNum) {
            System.out.println("有参构造方法:" + str + ", " + iNum);
        }
        
        private String key;
        private String value;
        
        public String getKey() {
            return key;
        }
        
        public void setKey(String key) {
            this.key = key;
        }
        
        public String getValue() {
            return value;
        }
        
        public void setValue(String value) {
            this.value = value;
        }
    }
    

8. 反射获取有参数构造方法并运行

  1. ComboListTest.java文件
    import java.lang.reflect.Constructor;
    
    public class ComboListTest {
        @SuppressWarnings({ "rawtypes", "unchecked" })
        public static void main(String[] args) throws Exception {
            Class c = Class.forName("com.ccblogs.inflect.ComboList");
            // 获取class文件对象中有参构造方法并运行
            Constructor con = c.getConstructor(String.class, int.class);
            con.newInstance("11", 2);
        }
    }
    
  2. ComboList.java文件
    public class ComboList {
        public ComboList() {
            System.out.println("无参构造方法");
        }
        
        public ComboList(String str, int iNum) {
            System.out.println("有参构造方法:" + str + ", " + iNum);
        }
        
        private String key;
        private String value;
        
        public String getKey() {
            return key;
        }
        
        public void setKey(String key) {
            this.key = key;
        }
        
        public String getValue() {
            return value;
        }
        
        public void setValue(String value) {
            this.value = value;
        }
    }
    

9. 反射获取构造方法并运行的快速方法

  1. ComboListTest.java文件
    public class ComboListTest {
        @SuppressWarnings({ "rawtypes" })
        public static void main(String[] args) throws Exception {
            Class c = Class.forName("com.ccblogs.inflect.ComboList");
            // Class类中定义方法,T newInstance()直接创建被反射类的对象实例
            // 快捷方式获取无参构造函数,被反射的类必须有无参构造函数,且该构造函数是public
            Object obj = c.newInstance();
            System.out.println(obj);
        }
    }
    
  2. ComboList.java文件
    public class ComboList {
        public ComboList() {
            System.out.println("无参构造方法");
        }
        
        public ComboList(String str, int iNum) {
            System.out.println("有参构造方法:" + str + ", " + iNum);
        }
        
        private String key;
        private String value;
        
        public String getKey() {
            return key;
        }
        
        public void setKey(String key) {
            this.key = key;
        }
        
        public String getValue() {
            return value;
        }
        
        public void setValue(String value) {
            this.value = value;
        }
    }
    

10. 反射获取私有构造方法并运行

推荐,破坏封装性和安全性。

  1. ComboList.java文件
    public class ComboList {
        public ComboList() {
            System.out.println("无参构造方法");
        }
        
        public ComboList(String str, int iNum) {
            System.out.println("有参构造方法:" + str + ", " + iNum);
        }
        
        @SuppressWarnings("unused")
        private ComboList(int iNum, String str) {
        }
        
        private String key;
        private String value;
        
        public String getKey() {
            return key;
        }
        
        public void setKey(String key) {
            this.key = key;
        }
        
        public String getValue() {
            return value;
        }
        
        public void setValue(String value) {
            this.value = value;
        }
    }
    
  2. ComboListTest.java文件
    import java.lang.reflect.Constructor;
    
    public class ComboListTest {
        @SuppressWarnings({ "rawtypes", "unchecked" })
        public static void main(String[] args) throws Exception {
            Class c = Class.forName("com.ccblogs.inflect.ComboList");
            Constructor con = c.getDeclaredConstructor(int.class, String.class);
            con.setAccessible(true);
            Object obj = con.newInstance(12, "34");
            System.out.println(obj);
        }
    }
    

11. 反射获取成员变量并改值

  1. ComboList.java文件
    public class ComboList {
        public ComboList() {
            System.out.println("无参构造方法");
        }
        
        public ComboList(String str, int iNum) {
            System.out.println("有参构造方法:" + str + ", " + iNum);
        }
        
        @SuppressWarnings("unused")
        private ComboList(int iNum, String str) {
        }
        
        public String key;
        public String value;
        
        public String getKey() {
            return key;
        }
        
        public void setKey(String key) {
            this.key = key;
        }
        
        public String getValue() {
            return value;
        }
        
        public void setValue(String value) {
            this.value = value;
        }
    }
    
  2. ComboListTest.java文件
    import java.lang.reflect.Constructor;
    
    public class ComboListTest {
        @SuppressWarnings({ "rawtypes" })
        public static void main(String[] args) throws Exception {
            Class c = Class.forName("com.ccblogs.inflect.ComboList");
            Field field = c.getField("key");
            Object obj = c.newInstance();
            field.set(obj, "keyId");
            System.out.println(obj);
        }
    }
    

12. 反射获取空参数成员方法并运行

  1. ComboList.java文件
    public class ComboList {
        public void setKey() {
            System.out.println("setKey********");
        }
        
        public void setValue(String value) {
            System.out.println("setValue********" + value);
        }
    }
    
  2. ComboListTest.java文件
    import java.lang.reflect.Method;
    
    public class ComboListTest {
        @SuppressWarnings({ "rawtypes", "unchecked" })
        public static void main(String[] args) throws Exception {
            Class c = Class.forName("com.ccblogs.inflect.ComboList");
            Object obj = c.newInstance();
            Method method = c.getMethod("setKey");
            method.invoke(obj);
        }
    }
    

13. 反射获取有参数的成员方法并运行

  1. ComboList.java文件
    public class ComboList {
        public void setKey() {
            System.out.println("setKey********");
        }
        
        public void setValue(String value) {
            System.out.println("setValue********" + value);
        }
    }
    
  2. ComboListTest.java文件
    import java.lang.reflect.Method;
    
    public class ComboListTest {
        @SuppressWarnings({ "rawtypes", "unchecked" })
        public static void main(String[] args) throws Exception {
            Class c = Class.forName("com.ccblogs.inflect.ComboList");
            Object obj = c.newInstance();
            Method method = c.getMethod("setValue", String.class);
            method.invoke(obj, "kkkkkkkkkkkkk");
        }
    }
    

14. 反射泛型擦除

  1. ComboListTest.java文件
    import java.lang.reflect.Method;
    import java.util.ArrayList;
    
    public class ComboListTest {
        @SuppressWarnings({ "unchecked", "rawtypes" })
        public static void main(String[] args) throws Exception {
            ArrayList<String> arrayList = new ArrayList<String>();
            arrayList.add("a");
            Class c = arrayList.getClass();
            Method method = c.getMethod("add", Object.class);
            method.invoke(arrayList, 1);
            method.invoke(arrayList, 2);
            System.out.println(arrayList);
        }
    }
    

15. 反射通过配置文件运行

  1. 工程下创建文件Config.properties
    className=com.ccblogs.inflect.ComboList
    methodName=setValue
    
  2. ComboList.java文件
    public class ComboList {
        public void setKey() {
            System.out.println("setKey********");
        }
        
        public void setValue(String value) {
            System.out.println("setValue********" + value);
        }
    }
    
  3. ComboListTest.java文件
    import java.io.FileReader;
    import java.lang.reflect.Method;
    import java.util.Properties;
    
    public class ComboListTest {
        @SuppressWarnings({ "unchecked", "rawtypes" })
        public static void main(String[] args) throws Exception {
            FileReader fr = new FileReader("Config.properties");
            Properties pr = new Properties();
            pr.load(fr);
            fr.close();
            String className = pr.getProperty("className");
            String methodName = pr.getProperty("methodName");
            Class c = Class.forName(className);
            Object obj = c.newInstance();
            Method method = c.getMethod(methodName, String.class);
            method.invoke(obj, "123");
        }
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值