1.什么是反射?
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
2.背景知识:
学习反射需要先了解一些基本概念:运行时,编译时,编译型,解释型,类加载器,动态加载类
什么是编译?将原程序翻译成计算机语言,就是二进制代码,在java中是将.java文件也就是源程序翻译成.class的字节码
什么是编译时?将原程序翻译成计算机语言的过程中,将.java翻译为.class文件的过程
什么是运行时?就是在启动这个程序的时候,在java中是,类加载器加载.class文件,并交给jvm处理
什么是编译型语言?将原程序一次性全部转换为二进制代码,然后执行程序
什么是解释型语言?转换一句,执行一句,java是既编译又解释的语言
编译型语言和解释型语言的区别:编译型语言效率高,依赖于编译器,但是跨平台差,解释型的效率低,依赖于解释器,但跨平台强
什么是类加载器?类加载器就是JVM中的类装载器,作用就是将编译好的.class字节码运到检查器进行安全检查的,检查通过后开始解释执行
什么是运行时动态加载类?
反射就是可以将一个程序(类)在运行的时候获得该程序(类)的信息的机制,也就是获得在编译期不可能获得的类的信息,因为这些信息是保存在Class对象中的,而这个Class对象是在程序运行时动态加载的
它就是可以在程序运行的时候动态装载类,查看类的信息,生成对象,或操作生成对象。
3.反射的实现:
1>得到Class类,有三种方式可以得到Class类:
2> 创建对象:获取类以后创建对象,使用newInstance();
Class c2 = Class.forName("reflectDemo.Person");
//创建此Class 对象所表示的类的一个新实例
Object p = c2.newInstance();
3>根据对象,可以获取对象的属性,方法,构造函数,事件等
得到所有的构造函数:
创建一个Person类,里面有四个构造函数:
package reflectDemo;
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name){
this.name=name;
}
public Person(int age){
this.age=age;
}
public Person(String name, int age) {
this.age=age;
this.name=name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString(){
return "["+this.name+" "+this.age+"]";
}
}
创建demo测试类:
package reflectDemo;
import java.lang.reflect.Constructor;
public class Demo {
public static void main(String[] args) {
Class<?> c2 = null;
try {
c2 = Class.forName("reflectDemo.Person");
Constructor<?>[] constructors = c2.getConstructors();
for(Constructor<?> constructor:constructors){
System.out.println(constructor );
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
输出结果为:
获取所有的属性:
package reflectDemo;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class Demo {
public static void main(String[] args) {
Class<?> c2 = null;
try {
c2 = Class.forName("reflectDemo.Person");
/* Constructor<?>[] constructors = c2.getConstructors();
for(Constructor<?> constructor:constructors){
System.out.println(constructor );
}*/
Field[] fileds = c2.getDeclaredFields();
StringBuffer sb = new StringBuffer();
//通过追加的方法,将每个属性拼接到此字符串中
//最外边的public定义
sb.append(Modifier.toString(c2.getModifiers()) + " class " + c2.getSimpleName() +"{\n");
//里边的每一个属性
for(Field field:fileds){
sb.append("\t");//空格
sb.append(Modifier.toString(field.getModifiers())+" ");//获得属性的修饰符,例如public,static等等
sb.append(field.getType().getSimpleName() + " ");//属性的类型的名字
sb.append(field.getName()+";\n");//属性的名字+回车
}
sb.append("}");
System.out.println(sb);
} catch (Exception e) {
e.printStackTrace();
}
}
}
输出结果为:
public class Person{
private String name;
private int age;
}
/**----------------------------------------------------------分割线------------------------------------------------------------------------*/
本文只是抛砖引玉,具体的使用参考API文档
未完待续:反射在设计模式中的使用。