详解Java高级特性之反射
定义
java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
用途
在日常的第三方应用开发过程中,经常会遇到某个类的某个成员变量、方法或是属性是私有的或是只对系统应用开放,这时候就可以利用java的反射机制通过反射来获取所需的私有成员或是方法。当然,也不是所有的都适合反射,之前就遇到一个案例,通过反射得到的结果与预期不符。阅读源码发现,经过层层调用后在最终返回结果的地方对应用的权限进行了校验,对于没有权限的应用返回值是没有意义的缺省值,否则返回实际值起到保护用户的隐私目的。
反射机制的相关类
与java反射相关的类如下:
类名 | 用途 |
class类 | 代表类的实体,在运行的java应用程序中表示类和接口 |
field类 | 代表类的成员变量(成员变量也称为类的属性) |
method类 | 代表类的方法 |
constructor类 | 代表类的构造方法 |
class类
class代表类的实体,在运行的java应用程序中表示类和接口。在这个类中提供了很多有用的方法,这里对他们简单的分类介绍。
获得类相关的方法
方法 | 用途 |
assubclass(class<u> clazz) | 把传递的类的对象转换成代表其子类的对象 |
cast | 把对象转换成代表类或是接口的对象 |
getclassloader() | 获得类的加载器 |
getclasses() | 返回一个数组,数组中包含该类中所有公共类和接口类的对象 |
getdeclaredclasses() | 返回一个数组,数组中包含该类中所有类和接口类的对象 |
forname(string classname) | 根据类名返回类的对象 |
getname() | 获得类的完整路径名字 |
newinstance() | 创建类的实例 |
getpackage() | 获得类的包 |
getsimplename() | 获得类的名字 |
getsuperclass() | 获得当前类继承的父类的名字 |
getinterfaces() | 获得当前类实现的类或是接口 |
获得类中属性相关的方法
方法 | 用途 |
getannotation(class<a> annotationclass) | 返回该类中与参数类型匹配的公有注解对象 |
getannotations() | 返回该类所有的公有注解对象 |
getdeclaredannotation(class<a> annotationclass) | 返回该类中与参数类型匹配的所有注解对象 |
getdeclaredannotations() | 返回该类所有的注解对象 |
获得类中构造器相关的方法
方法 | 用途 |
getconstructor(class...<?> parametertypes) | 获得该类中与参数类型匹配的公有构造方法 |
getconstructors() | 获得该类的所有公有构造方法 |
getdeclaredconstructor(class...<?> parametertypes) | 获得该类中与参数类型匹配的构造方法 |
getdeclaredconstructors() | 获得该类所有构造方法 |
获得类中方法相关的方法
方法 | 用途 |
getmethod(string name, class...<?> parametertypes) | 获得该类某个公有的方法 |
getmethods() | 获得该类所有公有的方法 |
getdeclaredmethod(string name, class...<?> parametertypes) | 获得该类某个方法 |
getdeclaredmethods() | 获得该类所有方法 |
类中其他重要的方法
方法 | 用途 |
isannotation() | 如果是注解类型则返回true |
isannotationpresent(class<? extends annotation> annotationclass) | 如果是指定类型注解类型则返回true |
isanonymousclass() | 如果是匿名类则返回true |
isarray() | 如果是一个数组类则返回true |
isenum() | 如果是枚举类则返回true |
isinstance(object obj) | 如果obj是该类的实例则返回true |
isinterface() | 如果是接口类则返回true |
islocalclass() | 如果是局部类则返回true |
ismemberclass() | 如果是内部类则返回true |
field类
field代表类的成员变量(成员变量也称为类的属性)。
方法 | 用途 |
equals(object obj) | 属性与obj相等则返回true |
get(object obj) | 获得obj中对应的属性值 |
set(object obj, object value) | 设置obj中对应属性值 |
method类
method代表类的方法。
方法 | 用途 |
invoke(object obj, object... args) | 传递object对象及参数调用该对象对应的方法 |
constructor类
constructor代表类的构造方法。
方法 | 用途 |
newinstance(object... initargs) | 根据传递的参数创建类的对象 |
示例
为了演示反射的使用,首先构造一个与书籍相关的model——book.java,然后通过反射方法示例创建对象、反射私有构造方法、反射私有属性、反射私有方法,最后给出两个比较复杂的反射示例——获得当前zenmode和关机shutdown。
被反射类book.java
public class book{ private final static string tag = "booktag"; private string name; private string author; @override public string tostring() { return "book{" + "name='" + name + '\'' + ", author='" + author + '\'' + '}'; } public book() { } private book(string name, string author) { this.name = name; this.author = author; } public string getname() { return name; } public void setname(string name) { this.name = name; } public string getauthor() { return author; } public void setauthor(string author) { this.author = author; } private string declaredmethod(int index) { string string = null; switch (index) { case 0: string = "i am declaredmethod 1 !"; break; case 1: string = "i am declaredmethod 2 !"; break; default: string = "i am declaredmethod 1 !"; } return string; } }
反射逻辑封装在reflectclass.java
public class reflectclass { private final static string tag = "peter.log.reflectclass"; // 创建对象 public static void reflectnewinstance() { try { class<?> classbook = class.forname("com.android.peter.reflectdemo.book"); object objectbook = classbook.newinstance(); book book = (book) objectbook; book.setname("android进阶之光"); book.setauthor("刘望舒"); log.d(tag,"reflectnewinstance book = " + book.tostring()); } catch (exception ex) { ex.printstacktrace(); } } // 反射私有的构造方法 public static void reflectprivateconstructor() { try { class<?> classbook = class.forname("com.android.peter.reflectdemo.book"); constructor<?> declaredconstructorbook = classbook.getdeclaredconstructor(string.class,string.class); declaredconstructorbook.setaccessible(true); object objectbook = declaredconstructorbook.newinstance("android开发艺术探索","任玉刚"); book book = (book) objectbook; log.d(tag,"reflectprivateconstructor book = " + book.tostring()); } catch (exception ex) { ex.printstacktrace(); } } // 反射私有属性 public static void reflectprivatefield() { try { class<?> classbook = class.forname("com.android.peter.reflectdemo.book"); object objectbook = classbook.newinstance(); field fieldtag = classbook.getdeclaredfield("tag"); fieldtag.setaccessible(true); string tag = (string) fieldtag.get(objectbook); log.d(tag,"reflectprivatefield tag = " + tag); } catch (exception ex) { ex.printstacktrace(); } } // 反射私有方法 public static void reflectprivatemethod() { try { class<?> classbook = class.forname("com.android.peter.reflectdemo.book"); method methodbook = classbook.getdeclaredmethod("declaredmethod",int.class); methodbook.setaccessible(true); object objectbook = classbook.newinstance(); string string = (string) methodbook.invoke(objectbook,0); log.d(tag,"reflectprivatemethod string = " + string); } catch (exception ex) { ex.printstacktrace(); } } // 获得系统zenmode值 public static int getzenmode() { int zenmode = -1; try { class<?> cservicemanager = class.forname("android.os.servicemanager"); method mgetservice = cservicemanager.getmethod("getservice", string.class); object onotificationmanagerservice = mgetservice.invoke(null, context.notification_service); class<?> cinotificationmanagerstub = class.forname("android.app.inotificationmanager$stub"); method masinterface = cinotificationmanagerstub.getmethod("asinterface",ibinder.class); object oinotificationmanager = masinterface.invoke(null,onotificationmanagerservice); method mgetzenmode = cinotificationmanagerstub.getmethod("getzenmode"); zenmode = (int) mgetzenmode.invoke(oinotificationmanager); } catch (exception ex) { ex.printstacktrace(); } return zenmode; } // 关闭手机 public static void shutdown() { try { class<?> cservicemanager = class.forname("android.os.servicemanager"); method mgetservice = cservicemanager.getmethod("getservice",string.class); object opowermanagerservice = mgetservice.invoke(null,context.power_service); class<?> cipowermanagerstub = class.forname("android.os.ipowermanager$stub"); method mshutdown = cipowermanagerstub.getmethod("shutdown",boolean.class,string.class,boolean.class); method masinterface = cipowermanagerstub.getmethod("asinterface",ibinder.class); object oipowermanager = masinterface.invoke(null,opowermanagerservice); mshutdown.invoke(oipowermanager,true,null,true); } catch (exception ex) { ex.printstacktrace(); } } public static void shutdownorreboot(final boolean shutdown, final boolean confirm) { try { class<?> servicemanager = class.forname("android.os.servicemanager"); // 获得servicemanager的getservice方法 method getservice = servicemanager.getmethod("getservice", java.lang.string.class); // 调用getservice获取remoteservice object oremoteservice = getservice.invoke(null, context.power_service); // 获得ipowermanager.stub类 class<?> cstub = class.forname("android.os.ipowermanager$stub"); // 获得asinterface方法 method asinterface = cstub.getmethod("asinterface", android.os.ibinder.class); // 调用asinterface方法获取ipowermanager对象 object oipowermanager = asinterface.invoke(null, oremoteservice); if (shutdown) { // 获得shutdown()方法 method shutdownmethod = oipowermanager.getclass().getmethod( "shutdown", boolean.class, string.class, boolean.class); // 调用shutdown()方法 shutdownmethod.invoke(oipowermanager, confirm, null, false); } else { // 获得reboot()方法 method rebootmethod = oipowermanager.getclass().getmethod("reboot", boolean.class, string.class, boolean.class); // 调用reboot()方法 rebootmethod.invoke(oipowermanager, confirm, null, false); } } catch (exception e) { e.printstacktrace(); } } }
调用相应反射逻辑方法
try { // 创建对象 reflectclass.reflectnewinstance(); // 反射私有的构造方法 reflectclass.reflectprivateconstructor(); // 反射私有属性 reflectclass.reflectprivatefield(); // 反射私有方法 reflectclass.reflectprivatemethod(); } catch (exception ex) { ex.printstacktrace(); } log.d(tag," zenmode = " + reflectclass.getzenmode());
log输出结果如下:
08-27 15:11:37.999 11987-11987/com.android.peter.reflectdemo d/peter.log.reflectclass: reflectnewinstance book = book{name='android进阶之光', author='刘望舒'}
08-27 15:11:38.000 11987-11987/com.android.peter.reflectdemo d/peter.log.reflectclass: reflectprivateconstructor book = book{name='android开发艺术探索', author='任玉刚'}
08-27 15:11:38.000 11987-11987/com.android.peter.reflectdemo d/peter.log.reflectclass: reflectprivatefield tag = booktag
08-27 15:11:38.000 11987-11987/com.android.peter.reflectdemo d/peter.log.reflectclass: reflectprivatemethod string = i am declaredmethod 1 !
08-27 15:11:38.004 11987-11987/com.android.peter.reflectdemo d/peter.log.reflectdemo: zenmode = 0
以上就是详解java高级特性之反射的详细内容,更多关于java高级特性反射的资料请关注其它相关文章!