Java反射机制探秘 桃扇骨 2021-11-11 05:08 284阅读 0赞 如何获得Class对象 1.针对每一个对象.getCalss(),可以得到对应的Class. 2.Class.forName(String),String的写法:包名.类名.就会创建包名.类名对应的那个对象 注:1.2只适用于引用类型 3.对于基本类型:封装类.TYPE代表了对应的基本类型的Class对象.Integer.TYPE对应的是int的Class对象 注:3只适用于基本类型 4.类型,Class。<第4种是通用的.> 上面的4种方法,只有方法2是动态的,只要换一个包就可以了.它具有动态潜质.所以真正意义的想体现动态编程只能使用方法2. 每种类型的Class对象只有一个,即他们的地址只有一个,但是不同类型是不同的. 所以下面的打印结果都为true. //对与引用类型 Class c1 = "".getClass(); Class c2 = Class.forName("java.lang.String"); Class c3 = String.class; System.out.println(c1 ==c2);//true //对于基本类型 Class num1 = Integer.TYPE; Class num2 = int.class; System.out.println(num1 == num2);//true 反射获取类中的成员的相关方法 \[获取构造<根据参数类型>\](使用时一般用不带declared的) Constructor<T> getConstructor(Class<?>... parameterTypes) 返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。 Constructor<?>[] getConstructors() 返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法。 Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法。 Constructor<?>[] getDeclaredConstructors() 返回 Constructor 对象的一个数组,这些对象反映此 Class 对象表示的类声明的所有构造方法。 \[获取属性<根据属性名>\](使用时一般用是带declared的,因为属性一般都是私有的) Field getField(String name) 返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段。 Field[] getFields() 返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段。 Field getDeclaredField(String name) 返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。 Field[] getDeclaredFields() 返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。 \[获取方法<方法名加上参数类型>\](使用时一般用不带declared的) Method getMethod(String name, Class<?>... parameterTypes) 返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。 Method[] getMethods() 返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法。 Method getDeclaredMethod(String name, Class<?>... parameterTypes) 返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。 Method[] getDeclaredMethods() 返回 Method 对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。 T newInstance() 创建此 Class 对象所表示的类的一个新实例。 <new Instance()可以动态的创建对象> String toString() 将对象转换为字符串。 注意: new Instance()调用的是无参构造,如果该类没有无参构造方法,则newInstance()会产生异常. 有declared的方法是支持私有,但是不支持继承,无declared的方法支持继承,不支持私有,且只能取出public的东西. 因此取属性的时候一般来说是带declared的,因为属性一般都是私有的,取方法时一般是不带declared的,取构造时一般也是不带declared的. **实例模拟反射获取类中的相关属性和方法** 利用反射对属性赋值 Field中的方法 Object get(Object obj) 返回指定对象上此 Field 表示的字段的值。 Field f = c.getXXField(属性名); 值 = f.get(对象); void set(Object obj, Object value) 将指定对象变量上此 Field 对象表示的字段设置为指定的新值。 f.set(对象,值); Class<?> getType() 返回一个 Class 对象,它标识了此 Field 对象所表示字段的声明类型。 用于获取属性的类型(返回Class对象). Class c = Student.class; Object obj = c.newInstance(); //创建Student类的对象 Field f = c.getDeclaredField("name"); //获取name属性 f.setAccessible(true); //设置私有可以访问. f.set(obj, "zhangsan"); System.out.println(f.get(obj)); //获取obj的name属性的值. 利用反射调用构造 对于构造真正调用是在调用newInstance()方法时. Class c = Class.forName("com.clazz.reflect.Student"); Constructor con = c.getConstructor(); //没有执行构造, Object cObj = c.getConstructor().newInstance();//调用无参的构造方法 Constructor conAll = c.getConstructor(int.class,String.class,int.class); Object caobj = conAll.newInstance(1001,"zjamgs",234235);//调用含参的构造方法. System.out.println(caobj); //打印输出 利用反射调用方法 对象.方法名(值1,2,3); Method m = c.getMethoed(方法名,参数类型...); m.invoke(对象,方法调用的参数 )如果底层方法所需的形参数为 0,则所提供的 args 数组长度可以为 0 或 null。 Class c = Class.forName("com.clazz.reflect.Student"); Object obj = c.newInstance(); //创建Sutdent对象. Method msetName = c.getMethod("setName", String.class);//obj无须转换类型 msetName.invoke(obj, "zhangsan");//调用方法setName, 并传参. Method msetId = c.getMethod("setId", int.class); msetId.invoke(obj, 409090202); System.out.println(obj); 反射应用实例 实体类 package org.dennisit.reflect.entity; import java.io.Serializable; /** * * User.java * * @version : 1.1 * * @author : 苏若年 <a href="mailto:DennisIT@163.com">发送邮件</a> * * @since : 1.0 创建时间: 2013-2-26 下午01:43:56 * * TODO : class User.java is used for ... * */ public class User implements Serializable{ private String test; public void execute(String name,int age){ System.out.println("name=" + name + ",age=" + age); } } 反射测试类 package org.dennisit.reflect.main; import java.lang.reflect.Field; /** * * ReflectEx.java * * @version : 1.1 * * @author : 苏若年 <a href="mailto:DennisIT@163.com">发送邮件</a> * * @since : 1.0 创建时间: 2013-2-26 下午01:46:00 * * TODO : class ReflectEx.java is used for ... * */ public class ReflectEx { public static void main(String[] args)throws Exception { Class cls = Class.forName("org.dennisit.reflect.entity.User"); Object obj = cls.newInstance(); //创建User的对象 Field f = cls.getDeclaredField("test"); //获取test属性 f.setAccessible(true); //打开私有属性test的访问权限 f.set(obj, "zhangsan"); //为test重新复制 System.out.println(f.get(obj)); //获取obj的test属性值 //根据方法名execute获取方法 java.lang.reflect.Method m = cls.getMethod("execute", String.class, int.class); m.invoke(obj, "dennisit",23); //调用execute方法 } } 运行效果 zhangsan name=dennisit,age=23 编写一个反射动态实例化类的例子 package org.dennisit.reflect.main; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Map; import java.util.Set; /** * * DynamicReflect.java * * @version : 1.1 * * @author : 苏若年 <a href="mailto:DennisIT@163.com">发送邮件</a> * * @since : 1.0 创建时间: 2013-2-26 下午01:58:12 * * TODO : 利用反射动态实例化的例子 * */ public class DynamicReflect { public static Object getInstance(String className,Map<String,Object> map)throws Exception{ Class c = Class.forName(className); Object obj = c.newInstance(); //对象对象 Set<String> keys = map.keySet(); //获取对应的所有属性 Field[] fAll = c.getDeclaredFields(); //获取类中所有属性 for(int i=0;i<fAll.length;i++){ for(String key:keys){ //循环匹配 if(fAll[i].getName().equals(key)){ //如果用户传入的属性跟获取到的类中的属性名匹配 Field f = c.getDeclaredField(key);//获取该属性 //构建setXxx()方法名 String methodName = "set" + key.substring(0,1).toUpperCase()+key.substring(1); Method method = c.getMethod(methodName, f.getType());//根据构建的用户名获取对应的方法 method.invoke(obj, map.get(key));//方法调用 }else{ continue; } } } return obj; } } 接下来我们测试我们编写的动态反射实例化例子 实体类 package org.dennisit.reflect.entity; import java.io.Serializable; /** * * User.java * * @version : 1.1 * * @author : 苏若年 <a href="mailto:DennisIT@163.com">发送邮件</a> * * @since : 1.0 创建时间: 2013-2-26 下午01:43:56 * * TODO : 实体类 * */ public class User implements Serializable{ private String name; private int age; private String email; public User() { //必须有无参构造 } //getter() and setter() } 主测试类 package org.dennisit.reflect.main; import java.util.HashMap; import java.util.Map; import org.dennisit.reflect.entity.User; /** * * ReflectEx.java * * @version : 1.1 * * @author : 苏若年 <a href="mailto:DennisIT@163.com">发送邮件</a> * * @since : 1.0 创建时间: 2013-2-26 下午01:46:00 * * TODO : class ReflectEx.java is used for ... * */ public class ReflectEx { public static void main(String[] args)throws Exception { Class cls = Class.forName("org.dennisit.reflect.entity.User"); String className = "org.dennisit.reflect.entity.User"; Map<String,Object> map = new HashMap<String, Object>(); map.put("name", "dennisit"); map.put("age", 22); map.put("email", "dennisit@163.com"); User user = (User)DynamicReflect.getInstance(className, map); System.out.println(user.getName() + "," + user.getAge() + "," + user.getEmail()); } } 程序运行结果 dennisit,22,dennisit@163.com 转载于:https://www.cnblogs.com/coprince/p/3145866.html
相关 使用Java反射机制探秘代码运行过程 在Java中,反射是一种能力,它可以让我们在运行时检查类、接口、方法和字段。这对于我们理解代码的运行过程是非常有价值的。 下面是一个简单的例子,通过反射获取一个类的所有方法: 本是古典 何须时尚/ 2024年09月21日 03:54/ 0 赞/ 8 阅读
相关 Java反射机制探秘:动态调用方法 Java的反射机制是一种强大的工具,它允许我们在运行时动态地获取类的信息,并且可以调用对象的方法。 以下是通过反射动态调用方法的基本步骤: 1. **获取Class对象** 傷城~/ 2024年09月20日 00:39/ 0 赞/ 7 阅读
相关 Java反射机制深度探析 Java反射机制是Java语言强大的特性之一,它允许我们在运行时获取类的信息,如方法、属性等,甚至可以动态创建对象。 深入探析反射机制主要包括以下几个方面: 1. 类和对象 快来打我*/ 2024年09月11日 16:06/ 0 赞/ 29 阅读
相关 Java反射机制探秘:动态调用方法和获取字段值的案例分析 Java反射机制是Java语言提供的一种允许程序在运行状态中了解类信息及对象相关信息的强大工具。 下面我们将通过几个实际案例来深入理解Java反射机制的应用: 1. 动态调 我不是女神ヾ/ 2024年09月11日 12:54/ 0 赞/ 17 阅读
相关 Ribbon IPing机制源码探秘 文章目录IPing机制用时间换空间?Ribbon IPing机制源码探秘IPing机制Ribbon会主动判断服务节点的当前状态,决定是否可作为目标节点,只有当前可用的节点... 朴灿烈づ我的快乐病毒、/ 2024年05月24日 21:38/ 0 赞/ 31 阅读
相关 Java:Thrift使用探秘 Thrift是apache提供的跨语言RPC调用框架,我们通过以下例子说明使用方法 tutorial.thrift: enum Operation { Love The Way You Lie/ 2022年09月29日 11:59/ 0 赞/ 16 阅读
相关 JAVA不定参数探秘 JAVA中可以使用不定参数, 例如 public void test(String ...args)\{...\} 这里test方法可以传入参数的情况是: 1.不使用参数, Dear 丶/ 2022年08月27日 01:29/ 0 赞/ 162 阅读
相关 Java反射机制探秘 如何获得Class对象 1.针对每一个对象.getCalss(),可以得到对应的Class. 2.Class.forName(String),St 桃扇骨/ 2021年11月11日 05:08/ 0 赞/ 285 阅读
相关 探秘Java虚拟机 一 点睛 不论是用控制台模式,还是Eclipse、Java编译器——javac,都会将源代码编译成 .class 这样的字节码文件,这样的文件,并不能如同可执行文件一样,双击 川长思鸟来/ 2021年09月19日 12:54/ 0 赞/ 389 阅读
还没有评论,来说两句吧...