Android开发者必知的Java知识(一):Java反射机制
来源:互联网 发布:python入门经典 下载 编辑:程序博客网 时间:2024/06/08 03:25
Android开发者必知的Java知识(一):Java反射机制
最近重新温习了一下java的反射机制,终结了一些东西,供大家参考
转载请注明出处:http://blog.csdn.net/qinjunni2014/article/details/44106243
1. 获取函数
getMethod
获取所有继承的方法,以及自己声明的public方法,
getDclaredMethod
获取所有自己单独声明的方法,不论处于什么访问状态
代码为证:
class MethodsDisplay { public static void displayMethods(Class clazz) throws Throwable { System.out.println("getMethods拿到的方法: "); Method[] methods = clazz.getMethods(); for (int i = 0; i < methods.length; i++) { Method method = methods[i]; System.out.println("方法名称 " + method.getName()); // System.out.println("param type " + // method.getParameterTypes().toString()); } } public static void displayDeclaredMethods(Class clazz) throws Throwable { System.out.println("getDeclaredMethods拿到的方法: "); Method[] methods = clazz.getDeclaredMethods(); for (int i = 0; i < methods.length; i++) { Method method = methods[i]; System.out.println("方法名称 " + method.getName()); // System.out.println("param type " + // method.getParameterTypes().toString()); } }}
getDeclaredMethods拿到的方法: 方法名称 name方法名称 hello方法名称 printh方法名称 smilegetMethods拿到的方法: 方法名称 smile方法名称 wait方法名称 wait方法名称 wait方法名称 equals方法名称 toString方法名称 hashCode方法名称 getClass方法名称 notify方法名称 notifyAll
调用私有函数
调用私有函数必须先调用getDeclaredMethod拿到函数, 而且必须在调用前,设置函数accessible
MyObject myObject = new MyObject(); Method method = MyObject.class.getDeclaredMethod("printh"); method.setAccessible(true); method.invoke(myObject);
调用构造函数
调用构造函数较为特殊,必须使用getDelcaredConstructor获得 一个类型为Constructor的实例,并调用newInstance构造对象
class Person { private String name; private int age; public Person() { System.out.println("default constructor"); } public Person(String _name, int _age) { name = _name; age = _age; System.out.println("Constructor with two int params"); } private void printh() { System.out.println("invoke private method"); } protected void name() { System.out.println(name); } void hello(){ System.out.println("hello"); } public void smile() { System.out.println("Smiling..."); }}
try { Class[] paramTypes = {String.class, int.class}; Constructor con = Person.class.getDeclaredConstructor(paramTypes); Person person = (Person) con.newInstance("LiLi",18); person.name();} catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace();}
Class.newInstance
创建对象,除了使用Constructor.newInstance方法外,还可使用Class.newInstance方法,但只限于无参默认构造函数:
Person p = Person.class.newInstance();p.smile();
如果我们注释掉Person中得无参构造函数, 则在运行上述代码时,会抛出Exception:
Exception in thread "main" java.lang.InstantiationException: Person at java.lang.Class.newInstance(Class.java:364) at ReflectMain.main(ReflectMain.java:47)
2. 获取变量
对于Field, 同样有两种获取的函数,getDeclaredField, getField…, 与获取函数一样,两种函数的区别在于 是否包含 继承的field以及private field
- getField: 获取继承的field以及声明的public field
- getDeclaredField: 获取自身声明的field
代码为证:
class Person { public static final String FEMALE = "female"; public static final String MALE = "male"; private String gender; public String name; private int age;}class Student extends Person{ public int level; private int score;}class FieldDisplay{ public static void displayFields(Class clazz) throws Throwable{ System.out.println("display getFields:"); Field[] fields = clazz.getFields(); for(int i=0;i< fields.length;i++){ Field field = fields[i]; System.out.println(field.getType()+ ": "+field.getName()); } } public static void displayDeclaredFields(Class clazz) throws Throwable{ System.out.println("display getDeclaredFields:"); Field[] fields = clazz.getDeclaredFields(); for(int i=0;i< fields.length;i++){ Field field = fields[i]; System.out.println(field.getType()+ ": "+field.getName()); } }}FieldDisplay.displayFields(Student.class);FieldDisplay.displayDeclaredFields(Student.class);
输出为:
display getFields:int: levelclass java.lang.String: FEMALEclass java.lang.String: MALEclass java.lang.String: namedisplay getDeclaredFields:int: levelint: score
访问私有变量只需对Field调用setAccessible(true)
获取Class
获取Class对象,有两种方法:
- 当我们能访问到该类时,例如Person类,我们可以直接调用Person.class 或者 Person类的对象person的getClass 方法
- 但我们无法访问该类时,我们如果知道该类的完整名称(包括包名),可以直接调用Class.forName进行类的加载
Class.forName
Class.forName有两种重载形式:
- Class.forName(String className)
- forName(String name, boolean initialize, ClassLoader loader) loader指定使用某个类加载器,initialize决定是否初始化
关于类加载器,我们在此不深究,有兴趣的可以参考Java官方文档.
好了,讲了这些Java 反射中最常用到的API,其实只是在为下一步讲解Java 中得annotation作铺垫,小哥即将下篇关于Annotation的介绍,敬请期待。
- Android开发者必知的Java知识(一):Java反射机制
- Android开发者必知的java知识(二)Annotation
- Android开发者必知的Java知识(四):Java并发编程
- Android开发者必知的Java知识(三) 结合注解分析ActiveAndroid的实现
- Java的反射机制(一)
- java反射---高级开发必须要懂的入门知识
- Java反射机制(一)
- Java反射机制一
- java反射机制 一
- JAVA反射机制(一)
- Java反射机制(一)
- java反射机制(一)
- JAVA反射机制知识讲解
- Java反射机制知识总结
- 必懂java、android知识
- java反射机制的实现原理 (一)
- java的method反射机制(一)
- Java的反射机制(一)
- JAVA设计模式(十四)——适配器模式
- Caffe + Ubuntu 14.04 64bit + CUDA 6.5 配置说明
- Linux内核驱动学习(六)----内核链表
- java 解惑
- Java一个简单的web服务器(支持简单的Servlet)
- Android开发者必知的Java知识(一):Java反射机制
- SGU 105 Div 3
- PatchMatch 相关
- My One And Only
- 浅析C/C++中new和malloc的区别
- windows下lammps并行版本的安装
- 分治法(最近点对)——HDU 1007
- CentOS下载及版本选择
- jdk源码之Collection接口