Java反射初探 ——“当类也学会照镜子”
反射的作用
好吧,我知道这听起来还是很模糊,让我们一步一步来:
类也是对象
“类”对象和“类”类型
Class a
取得Class对象的三种方式
public class MyClass { }
Class classInstance= MyClass.class;
二. 通过类创建的实例对象的getClass方法取得
MyClass myClass = new MyClass(); Class classInstance = myClass.getClass();
三.通过Class类的静态方法forName方法取得(参数是带包名的完整的类名)
Class classInstance = Class.forName("mypackage.MyClass");
try {Class classInstance = Class.forName("mypackage.MyClass"); } catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace(); }
利用反射API全面分析类的信息——方法,成员变量,构造器
public class MyClass {private int value; //成员变量public MyClass (int value) { this.value = value; } //构造函数public int getValue() { return value; } //方法1public void setValue(int value) { this.value = value; } //方法2 }
import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method;public class Test {public static void printClassMessage (Object obj) {Class c = obj.getClass(); // 获取obj所属类的Class对象Method [] methods = c.getDeclaredMethods(); // 获取方法对象列表 System.out.println("遍历MyClass类里的所有方法的名称:");for(int i =0; i<methods.length; i++) {System.out.println(methods[i].getName());}Field [] fields = c.getDeclaredFields(); // 获取成员变量对象列表System.out.println("遍历MyClass类里的所有成员变量的名称:");for(int i =0; i<fields.length; i++) {System.out.println(fields[i].getName());}Constructor [] constructors = c.getConstructors(); // 获取构造函数对象列表System.out.println("遍历MyClass类里的所有构造函数的名称:");for(int i =0; i<constructors.length; i++) {System.out.println(constructors[i].getName());}} public static void main(String [] args) {MyClass myClass = new MyClass(1); // 创建一个MyClass对象printClassMessage(myClass); // 打印这个对象所属类的相关信息} }
遍历MyClass类里的所有方法的名称: getValue setValue 遍历MyClass类里的所有成员变量的名称: value 遍历MyClass类里的所有构造函数的名称: mypackage.MyClass
上面的例子仅仅是作为一个展示,Method/Field/Constructor对象的API当然不仅限于getName这样获取名称的简单操作,所以接下来我将分别介绍更具体的反射API
利用反射API分析类中方法信息
getMethods和getDeclaredMethods方法
public Method[] getDeclaredMethods()对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。当然也包括它所实现接口的方法。
getValue setValue
import java.lang.reflect.Method;public class Test {public static void printMethodsMessage (Object obj) {Class c = obj.getClass();Method [] methods = c.getMethods();for (Method method : methods) {System.out.println(method.getName());}} public static void main(String [] args) {MyClass myClass = new MyClass(1);printMethodsMessage(myClass);} }
getValue setValue wait wait wait equals toString hashCode getClass notify notifyAll
通过method.getReturnType()获取方法返回值对应的Class对象
import java.lang.reflect.Method;public class Test {public static void printMethodsMessage (Object obj) {Class c = obj.getClass(); // 取得obj所属类对应的Class对象Method [] methods = c.getDeclaredMethods(); // 取得obj所属类中方法对应的Method对象组成的数组for (Method method : methods) { // 遍历Method对象String name = method.getName(); // 取得方法名Class returnClass = method.getReturnType(); // 获取方法返回值对应的Class对象String returnName = returnClass.getName(); //获取返回值所属类的类名——也即返回值类型System.out.println(name + "方法的返回值类型是" + returnName);}}public static void main(String [] args) {MyClass myClass = new MyClass(1);printMethodsMessage(myClass);}}
getValue方法的返回值类型是int setValue方法的返回值类型是void
通过method.getParameterTypes()获取方法各参数的Class对象组成的数组
public class MyClass {public void method1 (int a, long b) { };public void method2 (float a, double b) { };public void method3 (String str) { }; }
public class Test {public static void printMethodsMessage (Object obj) {Class c = obj.getClass(); // 取得obj所属类对应的Class对象Method [] methods = c.getDeclaredMethods(); // 取得obj所属类中方法对应的Method对象组成的数组for (Method method : methods) { // 遍历Method对象String methodName = method.getName(); // 取得方法名String paramsStr = ""; // 用于存放某个方法参数类型列表的字符串Class [] paramsClasses = method.getParameterTypes();for (Class pc: paramsClasses) {String paramStr = pc.getName(); // 获取当前参数类型paramsStr+=paramStr + " ";}System.out.println(methodName+ "方法的所有参数的类型列表:" + paramsStr);}}public static void main(String [] args) {MyClass myClass = new MyClass();printMethodsMessage(myClass);} }
method2方法的参数类型列表:float double method1方法的参数类型列表:int long method3方法的参数类型列表:java.lang.String
利用反射API分析类中成员变量信息
获取成员变量类型对应的的Class对象
public class MyClass {private int number = 123;private String name ="彭湖湾"; }
import java.lang.reflect.Field; import java.lang.reflect.Method;public class Test {public static void printFieldsMessage (Object obj) {Class c = obj.getClass(); // 取得obj所属类对应的Class对象try {Field field = c.getDeclaredField("name"); // 取得名称为name的field对象field.setAccessible(true); // 这一步很重要!!!设置为true才能访问私有成员变量name的值!String nameValue = (String) field.get(obj); // 获取obj中name成员变量的值System.out.println("MyClass类中name成员变量的值为:" + nameValue); // 输出} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();}} public static void main(String [] args) {MyClass myClass = new MyClass();printFieldsMessage(myClass);}}
MyClass类中name成员变量的值为:彭湖湾
通过getType方法读取成员变量类型的Class对象
Field field = class1.getDeclaredField(number"); System.out.print(field.getType().getName());
int
利用反射API分析类中构造器信息
public class MyClass {public MyClass(int a, String str){} }
import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method;public class Test {public static void printContructorsMessage (Object obj) {Class c = obj.getClass(); // 取得obj所属类对应的Class对象Constructor [] constructors = c.getDeclaredConstructors();for (Constructor constructor : constructors) {Class [] paramsClasses = constructor.getParameterTypes();String paramsStr = "";for (Class pc : paramsClasses) {String paramStr = pc.getName();paramsStr+=paramStr + " ";}System.out.println("构造函数的所有参数的类型列表:" + paramsStr);}}public static void main(String [] args) {MyClass myClass = new MyClass(1, "彭湖湾");printContructorsMessage(myClass);}}
构造函数的所有参数的类型列表:int java.lang.String
利用反射动态加载类,并用该类创建实例对象
NotExistClass cannot be resolved to a type
Class classInstance = Class.forName("mypackage.MyClass"); MyClass myClass = (MyClass) classInstance.newInstance();
不过要注意的是,因为newInstance返回的是一个Object,所以要做强制类型转换,将其变成MyClass类型
public class Test {public static void main(String [] args) {try {Class classInstance = Class.forName("mypackage.MyClass");MyClass myClass = (MyClass) classInstance.newInstance();} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (InstantiationException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();}} }
参考:利用反射实现JavaBean的自动赋值 import java.lang.reflect.Method; import java.util.*; import javax.servlet.http.HttpServletRequest; import com.sns.exception.ApplicationException; public final class ParameterUtil { public static void setFormBean(HttpServletRequest request, Object bean) { Class c = bean.getClass(); Method[] ms = c.getMethods(); for(int i=0; i<ms.length; i++) { String name = ms.getName(); if(name.startsWith("set")) { Class[] cc = ms.getParameterTypes(); if(cc.length==1) { String type = cc[0].getName(); // parameter type try { // get property name: String prop = Character.toLowerCase(name.charAt(3)) + name.substring(4); // get parameter value: String param = getString(request, prop); if(param!=null && !param.equals("")) { //ms.setAccessible(true); if(type.equals("java.lang.String")) { ms.invoke(bean, new Object[] {param}); } else if(type.equals("int") || type.equals("java.lang.Integer")) { ms.invoke(bean, new Object[] {new Integer(param)}); } else if(type.equals("long") || type.equals("java.lang.Long")) { ms.invoke(bean, new Object[] {new Long(param)}); } else if(type.equals("boolean") || type.equals("java.lang.Boolean")) { ms.invoke(bean, new Object[] { Boolean.valueOf(param) }); } else if(type.equals("java.util.Date")) { Date date = DateUtil.parseDateTime(param); if(date!=null) ms.invoke(bean, new Object[] {date}); } } } catch(Exception e) { e.printStackTrace(); } } } } } } 每当发现JavaBean中的setXxx()方法时,便自动寻找表单的对应字段xxx,如果找到,就利用反射调用此方法,将对应的字段值赋给JavaBean。 由于表单传递的变量名和值全部是字符串,因此需要做某些转换。目前,该程序能处理的数据类型包括:boolean,Boolean,int,Integer,long,Long,Date,不被支持的数据类型被自动忽略。你也可以很方便地添加新的类型。 请 注意,只有public的set方法能够被调用。如果你希望private或protected的set方法也能被调用,请将红色标识的 getMethods()改为getDeclaredMethods(),以便获得包括private和protected在内的所有方法,并将 ms.setAccessible(true);的注释去掉,以便能正确调用private和protected方法。 反射是Java语言非常强大的功能,但是由于反射会破坏对象封装,并且反射调用的速度较慢,因此,只能在必要的工具类中使用。
转载于:https://www.cnblogs.com/he-px/p/7597964.html
Java反射初探 ——“当类也学会照镜子”相关推荐
- java 反射获取实体类_Java 通过反射给实体类赋值操作
表单提交这个方法是挺方便的,但在java来说就显得有些麻烦了, 怎么个麻烦呢,就是当你字段多的时候,你就得一个一个的获取其对应的值,这样代码量就多了起来,其代码量不说,维护也是一个问题. 所以就有了这 ...
- 利用Java反射机制调用类的私有方法
利用Java反射机制调用类的私有方法 引言 来吧·展示 参考链接 引言 如何调用其他类的私有方法呢? 可以利用Java的反射机制,去调用其他类的私有方法 来吧·展示 package cn.learn. ...
- java 反射初探(1)
从接触java开始,很少使用过反射,记得只有在去年做一个舆情项目的时候,用反射做过一个代理模式来判断抓取的哪个网站的数据.先说说自己对反射的理解吧. 反射的原理: JAVA反射机制是在运行状态中,对于 ...
- java反射获取实体类_java 反射获取类对象的三种方式
Java反射经常用到的就是获取对象中的属性,那么Java获取类对象就是必不可少的啦! Java实体类: public class ReflexModel { private String code; ...
- JAVA反射和CLASS类
感谢原文作者:http://blog.sina.com.cn/s/blog_62a6ceb10100gwe0.html JAVA其实不算是一门动态语言,但JAVA中却又一种机制可以达到动态的某中效果, ...
- Java反射之Filed(类中的属性对象)
通过反射机制获取类中的属性对象. 1.获取类中所有的public属性(包括父类):getFields(): public class TestFiled {class A{public int age ...
- java 反射 单例类_利用反射机制破坏单例模式
简介 利用反射机制破坏了单例模式,这里以懒汉单例模式为例子进行操作. 之前利用反射也是改变了类中的private变量. 类中的private变量真的private么? 正常的单例模式的实现 这里采用了 ...
- java反射的工具类的函数集合
import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang ...
- java 反射 接口工具类_Java 反射工具类 ReflectionUtils
import lombok.extern.slf4j.Slf4j; import java.lang.reflect.*; /** * 反射的 Utils 函数集合 * 提供访问私有变量, 获取泛型类 ...
- java反射获取实现类_Java介绍通过反射获取类的信息
免费学习推荐:java基础教程 目录1.获取Field 2.反编译Field 3.通过反射机制访问对象属性 4.可变长度参数 5.反射Method(了解) 6.反编译(了解) 7.反射机制调用方法 8 ...
最新文章
- .net 无法通过嵌套类型访问外部类型的非静态成员-解决方案
- 让ie8、ie9支持媒体查询
- 带括号的计算器 java_【福利】java新手做的复合型计算器!
- 深度学习语义分割理论与实战指南
- java jint,JNI:将unsigned int转换为jint
- 数学之路(3)-机器学习(3)-机器学习算法-SVM[9]
- mysql受影响的行 0_为什么更新/删除成功时受影响的行返回0?
- 14岁的男孩说想学生信,应该给予哪些指导?
- ubuntu使用git时,终端不显示git分支。
- centos下使用yum命令安装php mcrypt扩展
- 分布式存储系统可靠性如何估算?
- iptables详解
- PLSQL 使用技巧(快捷键/关键字等)
- Nmap支持的TCP / IP 系统指纹识别方法
- 【QT】FillRect填充的区域实现部分区域透明
- Python学习_053.双分支选择结构_三元运算符的使用详解
- win10锁屏c语言,怎样在Win10锁屏界面打开任意应用程序【图文教程】
- 阿里笔试之Java分词统计
- 中国防静电塑料卷轴市场深度研究分析报告
- 【转】iOS开发人员必看的精品资料(100个)
热门文章
- 计算机应用基础 许晞课程标准,〔计算机应用基础〕课程标准.doc
- python ca模块_23 Python常用模块(一)
- linux7 ftp服务器,Centos7下搭建FTP服务器
- mysql 5.7.18源码包下载_centos 7 下MySQL 5.7.18 源码安装
- go语言json嵌套数组结构体用法
- c语言随机生成算式的对错判断,蔡奇宏软件工程第二次作业--四则运算
- 三、Spring Cloud的配置 之 服务提供者 配置
- 少样本学习系列(三)【Optimization-Based Methods】
- 自学elastic search
- HDU 5857 - Median ( 查询模拟 + 思路 )