收到礼物的女生都哭了java_新鲜出炉,深入讲解Java反射的底层原理,这篇算讲得不错了...

本文来源:https://segmentfault.com/a/1190000039302149?utm_source=tuicool&utm_medium=referral反射 Java代码和Java文件Java代码基本格式 1. Java代码都在类内或者接口内 2. class 类名 { 成员变量 构造方法 成员方法 Annotation 注解 }Java文件要求: 1. 通常情况下一个Java文件对应一个Java类 2. Java文件包含当前Java代码的所有内容!!!Java文件和.class字节码文件Java文件 FirstJava.java 通过编译器 javac ==> javac FirstJava.java ==> FirstJava.class.class字节码文件是什么??? 二进制可执行文件。 .class字节码文件中会包含Java文件的所有内容。 .class字节码文件包含Java程序的所有可执行内容(注释不参与编译和执行)。class字节码文件在内存中的位置

5d2dd03bae7fb5f4f59274a2533626f3.pngClass类相关方法Class Class.forName(String packageNameAndClassName) throws ClassNotFoundException; 根据完整的包名.类名获取对应的Class类对象 ClassNotFoundException 未找到指定类Class 类对象.getClass(); 通过类对象获取当前类对象对应的Class类对象 例如: Person p = new Person(); p.getClass() ==> Person类对应Class对象Class 类名.class; 通过类名获取当前类对应属性 Class对象 例如: Person.class ==> Person类对应Class对象。package com.qfedu.a_reflect;/** * Class类方法演示 * * @author 期年之前ying@ * */public class GetClassObject { public static void main(String[] args) throws ClassNotFoundException { /* * Class Class.forName(String packageNameAndClassName) * throws ClassNotFoundException; */ Class cls1 = Class.forName("com.project.a_reflect.Person"); /* * Class 类对象.getClass(); */ Person person = new Person(); Class cls2 = person.getClass(); /* * Class 类名.class; */ Class cls3 = Person.class; /* * 不管是通过哪一种方式获取指定类的Class对象,都是同一个Class对象 * 因为当前Person类在当前程序中有且只占用一次代码区空间。 */ System.out.println("cls1 == cls2 : " + (cls1 == cls2)); System.out.println("cls2 == cls3 : " + (cls2 == cls3)); System.out.println("cls3 == cls1 : " + (cls3 == cls1)); }}操作Constructor 构造方法类 通过Class类对象获取对应类的Constructor构造方法类对象Constructor[] getConstructors(); 获取当前Class对象对应类中所有非私有化构造方法类对象数组。 Constructor[] getDeclaredConstructors(); 【暴力反射】 获取当前Class对象对应类中的所有构造方法类对象数组,包括私有化构造方法。 Constructor getConstructor(Class... parameterTypes); 获取当前Class对象中,指定参数数据类型的构造方法。获取的构造方法为非私有化构造方法 Class... parameterTypes Class类型不定长参数,用于约束当前构造方法对应的数据类型。 例如: 无参数构造方法 cls.getConstructor(); ==> Person(); 两个参数构造方法(int, String) cls.getConstructor(int.class, String.class) ==> Person(int, String) Constructor getDeclaredConstructor(Class... parameterTypes); 【暴力反射】 获取当前Class对象中,指定数据类型的构造方法,包括私有化构造方法 例如: 获取私有化String类型构造方法 cls.getDeclaredConstructor(String.class) ==> private Person(String.class)操作Constructor类对象创建对应类对象Object newInstance(Object... parameters); 通过Constructor类对象,执行对应的构造方法,创建对应类对象 Object... 不定长参数,要求数据类型为Object类型。 例如: Person(); 无参数构造方法 Person p1 = (Person) constructor.newInstance(); Person(int, java.lang.String); Person p2 = (Person) constructor.newInstance(10, "Java真好学");package com.qfedu.a_reflect;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;/** * 操作Constructor构造方法类对象 * * @author 期年之前ying@ * */public class GetConstructorObject { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { /* * Class Class.forName(String packageNameAndClassName) * throws ClassNotFoundException; */ Class cls = Class.forName("com.project.a_reflect.Person"); /* * 1. 获取当前Class对象对应类中所有非私有化构造方法类对象数组 */ Constructor[] constructors = cls.getConstructors(); for (Constructor constructor : constructors) { System.out.println(constructor); } System.out.println(); /* * 2. 【暴力反射】 * 获取当前Class对象对应类中的所有构造方法类对象数组,包括私有化构造方法。 */ Constructor[] declaredConstructors = cls.getDeclaredConstructors(); for (Constructor constructor : declaredConstructors) { System.out.println(constructor); } System.out.println(); /* * 3. 获取当前Class对象中,指定参数数据类型的构造方法。获取的构造方法为非私有化构造方法 */ Constructor constructor1 = cls.getConstructor(); Constructor constructor2 = cls.getConstructor(int.class); Constructor constructor3 = cls.getConstructor(int.class, String.class); System.out.println(constructor1); System.out.println(constructor2); System.out.println(constructor3); /* * 4. 【暴力反射】 * 获取当前Class对象中,指定数据类型的构造方法,包括私有化构造方法 */ Constructor constructor4 = cls.getDeclaredConstructor(String.class); System.out.println(constructor4); System.out.println(); /* * newInstance 创建类对象 */ Person p1 = (Person) constructor1.newInstance(); Person p2 = (Person) constructor2.newInstance(10); Person p3 = (Person) constructor3.newInstance(20, "张三爱Java"); System.out.println(p1); System.out.println(p2); System.out.println(p3); /* * 给予暴力反射操作使用权限!!! * setAccessible(boolean flag); */ constructor4.setAccessible(true); Person p4 = (Person) constructor4.newInstance("Java快乐多"); System.out.println(p4); }}操作 Method 成员方法类 通过Class类对象获取对应类的Method成员方法类对象Method[] getMethods(); 通过Class类对象调用,获取当前类内的所有非私有化成员方法,包含从父类继承而来子类可以使用的非私有化方法。 Method[] getDeclaredMethods(); 【暴力反射】 通过Class类对象调用,获取当前类内的所有成员方法,包括私有化成员方法,但是不包括从父类继承而来的方法。 Method getMethod(String methodName, Class... parameterTypes); 通过Class类对象调用,根据方法名称和对应的形式参数列表数据类型获取对应的成员方法,可以获取父类继承方法,不能获取私有化成员方法 例如: 无参数成员方法 获取 game(); cls.getMethod("game"); 有参数成员方法 获取 game(String); cls.getMethod("game", String.class); Method getDeclaredMethod(String methodName, Class... parameterTypes); 通过Class类对象调用,根据方法名称和对应的形式参数列表数据类型获取对应的成员方法,可以获取私有化成员方法,不能获取父类成员方法。 例如: 无参数私有化成员方法 testPrivate(); cls.getDeclaredMethod("testPrivate"); 有参数私有化成员方法 testPrivate(String); cls.getDeclaredMethod("testPrivate", String.class);操作Method类对象执行方法Object invoke(Object obj, Object... parameters); 通过Method类对象调用,执行对应方法。 Object obj 执行当前方法的类对象。 Object... parameters 对应当前方法的实际参数列表package com.qfedu.a_reflect;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;/** * 操作Method类对象 * * @author 期年之前ying@ * */public class GetMethodObject { public static void main(String[] args) throws ClassNotFoundException, SecurityException, NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { /* * Class Class.forName(String packageNameAndClassName) * throws ClassNotFoundException; */ Class cls = Class.forName("com.project.a_reflect.Person"); /* * 1. 通过Class类对象调用,获取当前类内的所有非私有化成员方法, * 包含从父类继承而来子类可以使用的非私有化方法。 */ Method[] methods = cls.getMethods(); for (Method method : methods) { System.out.println(method); } System.out.println(); /* * 2. 获取当前类自有成员方法,包括私有化方法,但是不包含父类继承给子类的方法 */ Method[] declaredMethods = cls.getDeclaredMethods(); for (Method method : declaredMethods) { System.out.println(method); } System.out.println(); /* * 3. 根据指定方法名字和参数类型,获取非私有化成员方法 */ Method game1 = cls.getMethod("game"); Method game2 = cls.getMethod("game", String.class); System.out.println(game1); System.out.println(game2); System.out.println(); /* * 4. 根据指定的方法名称和参数类型,获取私有化成员方法 */ Method testPrivate1 = cls.getDeclaredMethod("testPrivate"); Method testPrivate2 = cls.getDeclaredMethod("testPrivate", String.class); System.out.println(testPrivate1); System.out.println(testPrivate2); System.out.println(); /* * 调用方法 */ Object object = cls.getConstructor().newInstance(); game1.invoke(object); game2.invoke(object, "World Of Tank"); /* * 给予暴力反射操作权限 */ testPrivate1.setAccessible(true); testPrivate2.setAccessible(true); testPrivate1.invoke(object); testPrivate2.invoke(object, "西红柿+黄瓜+鸡蛋+羊肉串"); }}操作 Field 成员变量类 通过Class类对象获取对应类的Field成员变量类对象Field[] getFields(); 获取类内所有非私有化成员变量数组 Field[] getDeclaredFields(); 【暴力反射】 获取类内所有成员变量数组,包括私有化成员变量Field getField(String fieldName); 根据成员变量名字获取对应的成员变量对象,要求当前成员变量非私有化 例如: public int test; cls.getField("test");Field getDeclaredField(String fieldName); 【暴力反射】 获取类内指定名字的成员变量对象,包括私有化成员变量 例如: private String name; private int id; cls.getDeclaredField("name"); cls.getDeclaredField("id");操作Field类对象赋值取值成员变量Field[] getFields(); 获取类内所有非私有化成员变量数组 Field[] getDeclaredFields(); 【暴力反射】 获取类内所有成员变量数组,包括私有化成员变量Field getField(String fieldName); 根据成员变量名字获取对应的成员变量对象,要求当前成员变量非私有化 例如: public int test; cls.getField("test");Field getDeclaredField(String fieldName); 【暴力反射】 获取类内指定名字的成员变量对象,包括私有化成员变量 例如: private String name; private int id; cls.getDeclaredField("name"); cls.getDeclaredField("id");package com.qfedu.a_reflect;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;/** * 操作Field类对象 * * @author 期年之前ying@ * */public class GetFieldObject { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException { /* * Class Class.forName(String packageNameAndClassName) * throws ClassNotFoundException; */ Class cls = Class.forName("com.project.a_reflect.Person"); /* * 1. 获取类内所有非私有化成员变量数组 */ Field[] fields = cls.getFields(); for (Field field : fields) { System.out.println(field); } System.out.println(); /* * 2. 获取类内所有成员变量数组,包括私有化成员变量 */ Field[] declaredFields = cls.getDeclaredFields(); for (Field field : declaredFields) { System.out.println(field); } System.out.println(); /* * 3. 根据成员变量名字获取对应的成员变量对象,要求当前成员变量非私有化 */ Field test = cls.getField("test"); System.out.println(test); System.out.println(); /* * 4. 获取类内指定名字的成员变量对象,包括私有化成员变量 */ Field id = cls.getDeclaredField("id"); Field name = cls.getDeclaredField("name"); System.out.println(id); System.out.println(name); System.out.println(); /* * 取值赋值成员变量 */ Object obj = cls.getConstructor().newInstance(); System.out.println(obj); test.set(obj, 100); System.out.println(obj); System.out.println(test.get(obj)); id.setAccessible(true); name.setAccessible(true); id.set(obj, 10); name.set(obj, "大哥好威武"); System.out.println(obj); System.out.println(id.get(obj)); System.out.println(name.get(obj)); System.out.println(); System.out.println(id.getType()); System.out.println(name.getType()); }}暴力反射授权class AccessibleObject 类内方法public static void setAccessible(AccessibleObject[] array, boolean flag); 通过类名调用的静态工具方式,给予AccessibleObject类对象或者其子类对象数组,赋值操作权限。 子类对象包括: Field Method Constructor public void setAccessible(boolean flag); 通过AccessibleObject类对象调用,单一权限授权,Field Method Constructor都可以使用。案例操作需要使用 1. String方法 2. IO流 推荐字符流操作 3. 反射 4. 自行了解 ==> String 转其他类型方法 百度 parse系列方法文件名: studentInfo.txt文件内容:className=com.qfedu.a_reflect.Studentname=李四age=18gender=falsejavaScore=59webScore=59dbScore=59目标 文件内容转Student类对象package com.qfedu.a_reflect;import java.io.BufferedReader;import java.io.FileReader;import java.io.IOException;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.util.Arrays;@SuppressWarnings("all")public class ReflectDemo { public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, NoSuchFieldException { // 1. 创建缓冲字符输入流 处理 文件 BufferedReader br = new BufferedReader(new FileReader("./data/studentInfo.txt")); // 2. 读取文件数据 String classInfo = br.readLine(); String className = classInfo.substring(classInfo.indexOf("=") + 1); // 3. 启动万恶之源 获取Class对象,加载指定类 Class cls = Class.forName(className); // 4. 创建对应类对象 Object obj = cls.getConstructor().newInstance(); // 5. 读取文件,利用循环操作 String info = null; Object value = null; // 每一次从文件中读取一行数据 while ((info = br.readLine()) != null) { // 按照 = 分割信息 name=李四 String[] split = info.split("="); System.out.println(Arrays.toString(split)); // 根据信息获取对应成员变量对象 Field field = cls.getDeclaredField(split[0]); field.setAccessible(true); // 获取成员变量数据类型 Class type = field.getType(); // 当前成员变量数据为String类型 if (type.equals(String.class)) { value = split[1]; // field.set(obj, split[1]); // 成员变量数据类型为int类型 } else if (type.equals(int.class)) { value = Integer.parseInt(split[1]); // 成员变量数据类型为boolean类型 } else if (type.equals(boolean.class)) { value = Boolean.parseBoolean(split[1]); } field.set(obj, value); } System.out.println(obj); // 关闭资源 br.close(); }}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值