@Yano
2017-08-07T00:50:59.000000Z
字数 4903
阅读 2314
Java
对于JDK源码分析的文章,仅仅记录我认为重要的地方。源码的细节实在太多,不可能面面俱到地写清每个逻辑。所以我的JDK源码分析,着重在JDK的体系架构层面,具体源码可以参考:http://www.cnblogs.com/skywang12345/category/455711.html。
在运行状态中,我们可以根据“类的部分已知的信息”来还原“类的全部的信息”。
public class User implements Serializable{private static final long serialVersionUID = 1510634274152200118L;private int id;private String passWord;public User() {System.out.println("Create user... ");}public User(int id, String passWord) {this.id = id;this.passWord = passWord;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getPassWord() {return passWord;}public void setPassWord(String passWord) {this.passWord = passWord;}@Overridepublic String toString() {return "User [id=" + id + ", passWord=" + passWord + "]";}}
根据类名,构造类的代码:
@Testpublic void testReflection() throws Exception {Class<?> clazz = Class.forName("test.User");User user = (User) clazz.newInstance();System.out.println("user = " + user);}
输出:
Create user...
user = User [id=0, passWord=null]
@Testpublic void testClazz() throws Exception {Class<?> clazz1 = Class.forName("test.User");Class clazz2 = User.class;Class clazz3 = new User().getClass();System.out.println("clazz1: " + clazz1);System.out.println("clazz2: " + clazz2);System.out.println("clazz3: " + clazz3);}
输出:
Create user...
clazz1: class test.User
clazz2: class test.User
clazz3: class test.User
// 获取“参数是parameterTypes”的public的构造函数public Constructor getConstructor(Class[] parameterTypes)// 获取全部的public的构造函数public Constructor[] getConstructors()// 获取“参数是parameterTypes”的,并且是类自身声明的构造函数,包含public、protected和private方法。public Constructor getDeclaredConstructor(Class[] parameterTypes)// 获取类自身声明的全部的构造函数,包含public、protected和private方法。public Constructor[] getDeclaredConstructors()// 如果这个类是“其它类的构造函数中的内部类”,调用getEnclosingConstructor()就是这个类所在的构造函数;若不存在,返回null。public Constructor getEnclosingConstructor()
测试:
@Testpublic void testConstructor() throws Exception {Class<?> clazz = Class.forName("test.User");Constructor<?> constructor = clazz.getDeclaredConstructor(null);Object object1 = constructor.newInstance();System.out.println(object1);Constructor<?> constructor2 = clazz.getDeclaredConstructor(new Class[] {int.class, String.class});Object object2 = constructor2.newInstance(1, "123456");System.out.println(object2);}
输出:
Create user...
User [id=0, passWord=null]
User [id=1, passWord=123456]
可以调用默认的构造函数,也可以通过
clazz.getDeclaredConstructor(new Class[] {int.class, String.class})
来调用User的含参构造函数
public User(int id, String passWord) {
this.id = id;
this.passWord = passWord;
}
// 获取“名称是name,参数是parameterTypes”的public的函数(包括从基类继承的、从接口实现的所有public函数)public Method getMethod(String name, Class[] parameterTypes)// 获取全部的public的函数(包括从基类继承的、从接口实现的所有public函数)public Method[] getMethods()// 获取“名称是name,参数是parameterTypes”,并且是类自身声明的函数,包含public、protected和private方法。public Method getDeclaredMethod(String name, Class[] parameterTypes)// 获取全部的类自身声明的函数,包含public、protected和private方法。public Method[] getDeclaredMethods()// 如果这个类是“其它类中某个方法的内部类”,调用getEnclosingMethod()就是这个类所在的方法;若不存在,返回null。public Method getEnclosingMethod()
可以判断类中是否含有某个方法,也可以调用类中的任何一个方法(包括私有方法)。
@Testpublic void testMethod() throws Exception {Class<?> clazz = Class.forName("test.User");Method[] declaredMethods = clazz.getDeclaredMethods();for (Method method : declaredMethods) {System.out.println(method);}System.out.println();Method printInfo = clazz.getDeclaredMethod("printInfo", new Class[]{});User user = (User) clazz.newInstance();printInfo.invoke(user, null);}
输出:
Create user...public java.lang.String test.User.toString()public int test.User.getId()public void test.User.printInfo()public void test.User.setId(int)public void test.User.setPassWord(java.lang.String)public java.lang.String test.User.getPassWord()User [id=0, passWord=null]
// 获取“名称是name”的public的成员变量(包括从基类继承的、从接口实现的所有public成员变量)public Field getField(String name)// 获取全部的public成员变量(包括从基类继承的、从接口实现的所有public成员变量)public Field[] getFields()// 获取“名称是name”,并且是类自身声明的成员变量,包含public、protected和private成员变量。public Field getDeclaredField(String name)// 获取全部的类自身声明的成员变量,包含public、protected和private成员变量。public Field[] getDeclaredFields()
@Testpublic void testField() throws Exception {Class<?> clazz = Class.forName("test.User");Field[] fields = clazz.getDeclaredFields();for (Field field : fields) {System.out.println(field);}// 创建并通过反射,修改一个 private 变量 idUser user = (User) clazz.newInstance();Field field = clazz.getDeclaredField("id");field.setAccessible(true);field.set(user, 123);user.printInfo();}
输出:
private static final long test.User.serialVersionUIDprivate int test.User.idprivate java.lang.String test.User.passWordCreate user...User [id=123, passWord=null]
我们可以看到,User中对于id的定义:
private int id;
而在测试用例中,可以获取对象中私有的id变量,并直接修改内容,最终输出的id=123。
// 获取类的"annotationClass"类型的注解 (包括从基类继承的、从接口实现的所有public成员变量)public Annotation<A> getAnnotation(Class annotationClass)// 获取类的全部注解 (包括从基类继承的、从接口实现的所有public成员变量)public Annotation[] getAnnotations()// 获取类自身声明的全部注解 (包含public、protected和private成员变量)public Annotation[] getDeclaredAnnotations()
// 获取实现的全部接口public Type[] getGenericInterfaces()// 获取父类public Type getGenericSuperclass()