1.反射原理
(1)动态链接
动态就是不对那些组成程序的目标文件进行链接,等到程序要运行时才进行链接。也就是说,把链接这个过程推迟到了运行时再进行,这就是动态链接(Dynamic Linking)的基本思想。
(2).class对象
在java里,类只是信息描述的,写明了有哪些内部属性及接口,你可以理解为是定义了一套规则;而Class对象在java里被用来对类的情况进行表述的一个实例,也就是是类的实际表征,可以理解为是对规则的图表化,这样JVM才能直观的看懂,可以看做是一个模版;而类的实例化对象,就是通过模版,开辟出的一块内存进行实际的使用。 基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也都对应一个 Class 对象。 每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。
(3)java程序执行过程
程序通过编译生成.class类型的目标文件,各个目标文件进行链接才能生成可执行文件。对于静态链接来说,就是把所有目标文件在程序执行之前链接到一块,生成可执行文件。但是对于动态链接来说,是边运行边装载,只有运行用到了才把该目标文件装载进入内存作为可执行文件的一部分。
Java的反射机制是编译时候并不知道哪一个类被加载了,而是在程序运行时才加载、探知、使用。这样的特点就是反射。这类似光学中反射的概念。在计算机科学领域,反射是指一类应用,他们能够自描述和自控制。
无论是程序还是数据只有装进入内存才能使用,通过反射机制,我们可以把我们想要操作的类装到内存中,实现对该类的操作。
2.反射机制优点
java的反射机制就是增加程序的灵活性,避免将程序写死到代码里,例如: 实例化一个 person()对象, 不使用反射, new person(); 如果想变成 实例化 其他类, 那么必须修改源代码,并重新编译。使用反射: class.forName("person").newInstance(); 而且这个类描述可以写到配置文件中,如 **.xml, 这样如果想实例化其他类,只要修改配置文件的"类描述"就可以了,不需要重新修改代码并编译。
3.反射的应用
3.1创建对象
package reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Date;
public class newInstance {
public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException,
SecurityException, IllegalArgumentException, InvocationTargetException {
// 直接实例化
Class cla = Date.class;
Date d = (Date) cla.newInstance();
System.out.println(d.toString());
// 通过构造函数实例化
Class cla1 = Date.class;
Constructor cu = cla1.getConstructor(long.class);
Date d1 = (Date) cu.newInstance(1987);
System.out.println(d1);
}
}
3.2访问类的属性
package reflect;
import java.lang.reflect.Field;
class Student {
private String name;
private String age;
@Override
public String toString() {
return "student [name=" + name + ", age=" + age + "]";
}
}
public class modField {
public static void main(String[] args)
throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
Student stu = new Student();
Class cla = Student.class;
Field nameFiled = cla.getDeclaredField("name");
nameFiled.setAccessible(true);
nameFiled.set(stu, "jack");
Field ageFiled = cla.getDeclaredField("age");
ageFiled.setAccessible(true);
nameFiled.set(stu, "12");
System.out.println(stu);
}
}
3.3访问类的方法
package reflect;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
class Student_ {
private String name;
private String age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
public class getMethod {
public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException {
Student_ stu = new Student_();
Class cla = Student_.class;
Method me1 = cla.getMethod("setName", String.class);
me1.setAccessible(true);
me1.invoke(stu, "jack");
Method me2 = cla.getMethod("getName", null);
me2.setAccessible(true);
Object o = me2.invoke(stu, null);
System.out.println(o);
}
}