Effective Java(Java的反射机制)
2016-07-11 22:02
537 查看
在第三条用私有构造器或者枚举类型强化Singleton属性中提到了反射机制可以调用类的私有化构造器,于是便查了一些关于反射机制的资料,以求能够最后实现通过反射来调用私有化构造器
基础知识
定义:
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这照片那个动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制
Java反射机制主要提供了以下功能:
<1>在运行时判断任意一个对象所属的类
<2>在运行时构造任意一个类的对象
<3>在运行时判断任意一个所具有的成员变量和方法
<4>在运行时调用任意一个对象的方法
Java Reflection API简介
在JDK中,主要由以下类来实现Java反射机制,除第一个外,这些类都位于java.lang.reflect包中
Class类:代表一个类,位于java.lang包下
Field类:代表类的成员变量
Method类:代表类的方法
Constructor类:代表类的构造方法
Array类:提供了动态创建数组,以及访问数组的元素的静态方法
获取Class对象的3中方式
<1>使用Class类的静态方法
Class.forName("包名"); 例:Class.forName("java.lang.String");
<2>使用类的.class语法
类名.class 例:String.class
<3>使用对象的getClass()方法
例:
String str="aa";
Class<?> classType=str.getClass();
通过Class类获取成员变量,成员方法,接口,超类,构造方法等
在java.lang.Object类中定义了getClass()方法,因此对于任意一个Java对象,都可以通过此方法获得对象的类型。
Class类是Reflection API中的核心类,它有以下方法:
getName():获得类的完整名字。
getFields():获得类的public类型的属性。
getDeclaredFields():获得类的所有属性。
getMethods():获得类的public类型的方法。
getDeclaredMethods():获得类的所有方法。
getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes 参数指定方法的参数类型。
getConstructors():获得类的public类型的构造方法。
getConstructor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes 参数指定构造方法的参数类型。
newInstance():通过类的不带参数的构造方法创建这个类的一个对象。
下面举个例子,实现获取String对象的所有方法
通过反射使用类中的方法
下面基本上可以实现利用反射调用私有方法,访问私有对象
(注意,以Method为例,getMethod()方法返回的是public的Method对象,而getDeclaredMethod()返回的Method对象可以是非public的)
访问私有属性和方法,在使用前要通过AccessibleObject类中的setAccessible()方法来抑制Java访问权限的检查
代码如下:
利用反射实现私有化构造方法的类的实例化
反射实现代码
参考:
http://www.cnblogs.com/mengdd/archive/2013/01/26/2877972.html
http://gaoquanyang.iteye.com/blog/1160561
基础知识
定义:
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这照片那个动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制
Java反射机制主要提供了以下功能:
<1>在运行时判断任意一个对象所属的类
<2>在运行时构造任意一个类的对象
<3>在运行时判断任意一个所具有的成员变量和方法
<4>在运行时调用任意一个对象的方法
Java Reflection API简介
在JDK中,主要由以下类来实现Java反射机制,除第一个外,这些类都位于java.lang.reflect包中
Class类:代表一个类,位于java.lang包下
Field类:代表类的成员变量
Method类:代表类的方法
Constructor类:代表类的构造方法
Array类:提供了动态创建数组,以及访问数组的元素的静态方法
获取Class对象的3中方式
<1>使用Class类的静态方法
Class.forName("包名"); 例:Class.forName("java.lang.String");
<2>使用类的.class语法
类名.class 例:String.class
<3>使用对象的getClass()方法
例:
String str="aa";
Class<?> classType=str.getClass();
通过Class类获取成员变量,成员方法,接口,超类,构造方法等
在java.lang.Object类中定义了getClass()方法,因此对于任意一个Java对象,都可以通过此方法获得对象的类型。
Class类是Reflection API中的核心类,它有以下方法:
getName():获得类的完整名字。
getFields():获得类的public类型的属性。
getDeclaredFields():获得类的所有属性。
getMethods():获得类的public类型的方法。
getDeclaredMethods():获得类的所有方法。
getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes 参数指定方法的参数类型。
getConstructors():获得类的public类型的构造方法。
getConstructor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes 参数指定构造方法的参数类型。
newInstance():通过类的不带参数的构造方法创建这个类的一个对象。
下面举个例子,实现获取String对象的所有方法
import java.lang.reflect.Method; public class DumpMethods { public static void main(String[] args) throws Exception { //获取字符串类 Class<?> classType=Class.forName("java.lang.String"); //返回字符串类中的所有方法的数组 Method[] methods=classType.getDeclaredMethods(); //遍历输出 for(Method method:methods){ System.out.println(method); } } }
通过反射使用类中的方法
import java.lang.reflect.Method; public class InvokeTester { public int add(int param1,int param2){ return param1+param2; } public String echo(String message){ return "Hello: "+message; } public static void main(String[] args) throws Exception { //获取Class对象 Class<?> classType=InvokeTester.class; //用newInstance()方法生成新的对象,并判断是否是InvokeTester对象 Object invokeTester=classType.newInstance(); System.out.println(invokeTester instanceof InvokeTester); //首先需要获得与该方法对应的Method对象,第一个参数时方法名;第二个参数是一个Class数组,用来装置参数类 Method addMethod=classType.getMethod("add", new Class[]{int.class,int.class}); //调用目标方法,第一个参数是类的对象,第二个参数是方法参数对象集合 Object result=addMethod.invoke(invokeTester, new Object[]{1,2}); System.out.println(result); //同理 Method echoMethod=classType.getDeclaredMethod("echo", new Class[]{String.class}); Object result2=echoMethod.invoke(invokeTester, new Object[]{"Tom"}); System.out.println(result2); } }
下面基本上可以实现利用反射调用私有方法,访问私有对象
(注意,以Method为例,getMethod()方法返回的是public的Method对象,而getDeclaredMethod()返回的Method对象可以是非public的)
访问私有属性和方法,在使用前要通过AccessibleObject类中的setAccessible()方法来抑制Java访问权限的检查
代码如下:
public class PrivateClass { private String sayHello(String name){ return "Hello:"+name; } }下面的代码实现访问上面类的私有方法
import java.lang.reflect.Method; public class TestPrivate { public static void main(String[] args) throws Exception { PrivateClass p=new PrivateClass(); Class<?>classType=p.getClass(); Method method=classType.getDeclaredMethod("sayHello", new Class[]{String.class}); method.setAccessible(true); String string=(String)method.invoke(p, new Object[]{"zhangsan"}); System.out.println(string); } }
利用反射实现私有化构造方法的类的实例化
public class PrivateClass2 { private PrivateClass2(){ // } public void sendMsg(){ System.out.println("私有化对象实例化成功"); } }
反射实现代码
import java.lang.reflect.Constructor; public class TestPrivate2 { public static void main(String[] args) throws Exception{ //类的获取 Class<?> classType=PrivateClass2.class; //获取无参构造函数, Constructor constructor=classType.getDeclaredConstructor(); //抑制Java访问控制检查 constructor.setAccessible(true); //这个newInstance之前一直见到的是类去新建一个对象,现在是直接用构造器来新建对象 PrivateClass2 privateClass2=(PrivateClass2)constructor.newInstance(); //调用公有方法 privateClass2.sendMsg(); } }
参考:
http://www.cnblogs.com/mengdd/archive/2013/01/26/2877972.html
http://gaoquanyang.iteye.com/blog/1160561
相关文章推荐
- js内存泄漏
- JS第五天总结
- CSS3新属性 border-radius版企鹅
- Controller之间的通信方式
- 实战Angular2+web api增删改查 (二)
- CSS样式覆盖规则
- 旋转的魔方-3D
- 用js制作163登陆页面终极版(写了一晚上)
- 对于bootstrap 的栅栏系统的屏幕适应的大小问题
- 关于(function($){...})(jQuery)匿名函数的笔记
- Libgdx之JSON文件解析
- json解析
- HTML5的浏览器支持方案
- html5画布
- 当div中插入图片时,图片下方有空隙的解决办法!
- jQuery进行图片预先加载
- 剑指offer系列-T17合并两个排序的链表
- 前端基础5 表单
- react 项目搭建
- JavaScript事件类型(一)