以下是我对java的反射机制所产生的一些感悟,希望各位童鞋看到失误之处不吝指出
一,WHAT?
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
二,HOW?
首先,你要获得类对象(注意一下类对象和类的对象的区别,不知道的嘛,就自己查查看吧,这里不做赘述)
那么,什么是类对象?其实就是Class对象。
Java程序在运行时,Java运行时系统会对所有的对象进行所谓的运行时类型标识。这项信息纪录了每个对象所属的类。虚拟机通常使用运行时类型信息,选准正确方法去执行,用来保存这些类型信息的类是Class类。In other word ! ClassLoader(听名字就会知道是类的加载器)找到了需要调用的类时(java为了调控内存的调用消耗,类的加载都在需要时再进行),就会加载它,然后根据.class文件内记载的类信息来产生一个与该类相联系的独一无二的Class对象。该Class对象记载了该类的字段,方法等等信息。以后JVM要产生该类的实例,就是根据内存中存在的该Class类所记载的信息来进行。
怎么获取类对象呢?获取Class对象有三种方式:
1.通过Object类的getClass()方法。
例如:Class c1 = new String("").getClass();
2.通过Class类的静态方法——forName()来实现:
Class c2 = Class.forName("MyObject");
3.如果T是一个已定义的类型的话,在java中,它的.class文件名:T.class就代表了与其匹配的Class对象,例如:
Class c3 = Manager.class;
Class c4 = int.class;
Class c5 = Double[].class;
然后,调用类对象的相关的方法来达到你所想要的目的你的目的大致可以分为
操作私有的方法(包括构造方法)
操作私有的属性
构建对象下面,
好了,接下来用代码来说明一切。因为读代码加上自己理解是最好的程序员学习方式。
class Student{
private int age = 10;
private int weight = 80;
public Student(){System.out.println("Hello");}
public Student(int age, int weight) {
this.age = age;
this.weight = weight;
}
public String toString() {
return "Student [age=" + age + ", weight=" + weight + "]";
}
private void show(int id){
System.out.println(id+"");
}
}
public class ReflectorDemo03 {
public static void main(String[] args) {
try{
//创建类对象
Class<?> student = Student.class;
//获得所有的类中的属性,不过类中的所有的东西都是对象,打印出来的都是对象的内存地址
Field[] f = student.getDeclaredFields();
for (Field field : f) {
System.out.println(f);
}
//得到指定的属性
Field f0 = student.getDeclaredField("age");
System.out.println(f0);
//获得一个Student对象
Student student2 = (Student) student.newInstance();
//设置成为可以访问类中的私有属性
f0.setAccessible(true);
//给私有的属性赋值
f0.set(student2, 60);
System.out.println(student2);
// 获得一个特定的方法
Method method = student.getDeclaredMethod("show",int.class);
// 设置为可以访问私有的方法
method.setAccessible(true);
// 执行方法
method.invoke(student2, 10000);
//得到类中的所有的构造器
Constructor<?>[] constructors = student.getDeclaredConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println(constructors);
}
//得到特定的构造器
Constructor<?> con = student.getConstructor(int.class,int.class);
//(因为用类对象的newInstance方法构造类的对象的前提是你的类中必须有无参的构造方法)
//但是用反射也可以实现 利用带参的构造方法得到一个Student类的对象
Student student3 = (Student) con.newInstance(80,80);
System.out.println(student3);
}catch(Exception e){
e.printStackTrace();
}
}
}
output:/*
[Ljava.lang.reflect.Field;@15db9742
[Ljava.lang.reflect.Field;@15db9742
private int day1019_reflectorDemo.Student.age
Hello
Student [age=60, weight=80]
10000
[Ljava.lang.reflect.Constructor;@6d06d69c
[Ljava.lang.reflect.Constructor;@6d06d69c
Student [age=80, weight=80]
*/