Java反射机制浅析
2015-11-17 22:03
344 查看
概述:
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。本文链接:http://blog.csdn.net/lemon_tree12138/article/details/49871515
--
Coding-Naga
--转载请注明出处
反射的基本操作:
1.获得类名
通过Java的反射机制我们可以获得一个对象的类。这里的类是类的全名,包含包名。比如:org.demo.reflect.Clazz.可能你会问,这个功能有什么用?其实这个功能还是很有用的。比如,我们在打日志的时候,我们就要用到这个功能,来追踪这个日志是在什么地方被打出来的。
private String getObjectName(Object o) { if (o == null) { return null; } return o.getClass().getName(); }
2.输出一个类的所有对外可见的变量
注意这里是输出所有对外可见的变量,即变量的修饰符为public.这里使用的是getFields()方法。注意,这里是可以获得其父类中的public变量.private void printFields(String clazzName) { try { Class<?> clazz = Class.forName(clazzName); Field[] fields = clazz.getFields(); for (Field field : fields) { System.out.println(field); } } catch(ClassNotFoundException e) { e.printStackTrace(); } }
3.输出一个类的所有成员变量
这里是输出一个类的成员变量,不论它是不是对外可见的。就算它是被private修饰,也同样可见。这一点很让人着迷,不是吗?这里使用的是getDeclaredFields()。
private void printDeclaredFields(String clazzName) { try { Class<?> clazz = Class.forName(clazzName); Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { System.out.println(field); } } catch(ClassNotFoundException e) { e.printStackTrace(); } }
4.输出一个类的所有public方法
这里与之前的getFields()类似只能对外可见的,即修饰符为public的方法。同样,这里也是可以获得父类的public方法。private void printMethods(String clazzName) { try { Class<?> clazz = Class.forName(clazzName); Method[] methods = clazz.getMethods(); for (Method method : methods) { System.out.println(method); } } catch(ClassNotFoundException e) { e.printStackTrace(); } }
5.输出一个类的所有成员方法
private void printDeclaredMethods(String clazzName) { try { Class<?> clazz = Class.forName(clazzName); Method[] methods = clazz.getDeclaredMethods(); for (Method method : methods) { System.out.println(method); } } catch(ClassNotFoundException e) { e.printStackTrace(); } }
6.调用类里面的成员函数
这里我先假设测试类中有一个sayHello方法,如下:public void sayHello(String from) { System.out.println("Hello from " + from); }
下面就可以通过getMethod()方法来反射获得这个sayHello方法。getMethod()中第一个参数为方法名,这里即是"sayHello",后面的参数是可变量参数,是可以填写0个或是多个的,值为被反射的方法中的参数类型。这里即是String.class。
然后再调用invoke()方法,invoke()的第一个参数为被反射的对象,后面是向sayHello()方法中传递的数据。具体过程如下:
private void callMethod(Object o, String clazzName) { try { Class<?> clazz = Class.forName(clazzName); Method method = clazz.getMethod("sayHello", String.class); method.invoke(o, TestReflect.class.getSimpleName()); } catch(Exception e) { e.printStackTrace(); } }
7.生成一个不能new的对象
可以看到上面的操作过程,都有一个前提,就是我们已经有了这个对象。那如果我们之前没有这个对象呢?或者说,我们不能显式地获得这个对象。这一点在学习单例模式的时候,就知道其实很好获得,只要把重写默认的构造方法,并把这个构造方法的修饰符修改为private即可。如下:private PrivateClass() { }
这里有一点比较特殊,就是这里使用的类或是方法都是私有的。我们不能直接去使用他们,在使用他们之前,需要设置其可访问性为true。具体操作过程如下:
private void newPrivateClass(String clazzName) { try { Class<?> clazz = Class.forName(clazzName); Constructor<?> constructor = clazz.getDeclaredConstructor(); constructor.setAccessible(true); PrivateClass privateClass = (PrivateClass)constructor.newInstance(); Method method = clazz.getDeclaredMethod("sayHello"); method.setAccessible(true); method.invoke(privateClass); } catch (Exception e) { e.printStackTrace(); } }
GitHub源码连接:
https://github.com/William-Hai/TestReflect相关文章推荐
- Java实用手册
- Myeclipse导入项目报错
- Elasticsearch[2.0] ☞ Java Client API ☞ Percolate API
- Java垃圾回收机制
- 认识Java
- JNI中的java类参数传递
- 将《Android应用开发揭秘》例子源码添加进Eclipse
- Java Web开发环境配置
- SSM框架——详细整合教程(Spring+SpringMVC+MyBatis)
- Java创建字符串是用“”还是用构造器?
- 二叉树的实现Java版本
- Android eclipse 常见的小问题
- Java实现最简单局域网QQ
- 【持久化框架】SpringMVC+Spring4+Mybatis3集成,开发简单Web项目+源码下载
- java 在MySQL中存储文件,读取文件(包括图片,word文档,excel表格,ppt,zip文件等)
- 【SSH进阶之路】Struts + Spring + Hibernate 进阶开端(一)
- 传智播客 刘意_2015年Java基础视频-深入浅出精华版 笔记(day11~)(2016年1月27日13:12:11)
- 相关SpringSecurity对于部分菜单隐藏的相关代码
- Spring Security 取Session中的值和修改userDetails
- 阿里云Ubuntu下部署javaWeb项目