JAVA反射机制是在运行状态中,对于任意一个类(class文件),都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。即:动态获取类中信息,就是java反射,可以理解为对类的解剖。也就是说,想要对一个类文件进行解剖,只要获取到该类的字节码文件对象即可。
在java中,Class类提供获取字节码文件中的内容,比如:名称、字段、构造函数、一般函数等。Class类就可以获取字节码文件中所有的内容,反射就是依靠该类完成的。
反射技术大大提高了程序的扩展性。
要想对字节码文件进行解剖,必须要有字节码文件对象,如何获取字节码文件对象呢?
定义一个Person类(在我自定义的包text下):
public class Person {
private int age;
private String name;
public Person(int age, String name) {
super();
this.age = age;
this.name = name;
System.out.println("Person param run..."+this.name+":"+this.age);
}
public Person() {
super();
System.out.println("person run");
}
public void show(){
System.out.println(name+"...show run..."+age);
}
private void method(){
System.out.println(" method run ");
}
public void paramMethod(String str,int num){
System.out.println("paramMethod run......."+str+":"+num);
}
public static void staticMethod(){ //静态方法
System.out.println(" static method run........");
}
}
获取字节码对象的方式:
1、Object类中的getClass方法。想要用这种方式,必须要明确具体的类并创建对象,较麻烦。
public class ReflectDemo {
public static void main(String[] args) {
getClassObject_1();
}
//方式一:
public static void getClassObject_1(){
Person p=new Person();
Class clazz = p.getClass(); //返回值是一个Class
Person p1=new Person();
Class clazz1=p1.getClass();
System.out.println(clazz==clazz1);
}
}
运行结果:
2、任何数据类型都具备一个静态的属性.class来获取其对应的Class对象。相对简单,但是还是要明确用到类中的静态成员。还是不够扩展。
public class ReflectDemo {
public static void main(String[] args) {
getClassObject_2();
}
//方式二
public static void getClassObject_2(){
Class clazz=Person.class;
Class clazz1=Person.class;
System.out.println(clazz==clazz1);
}
}
运行结果:
3、( 重点)只要通过给定的类的字符串名称就可以获取该类,更为扩展。可以用Class类中的方法完成,该方法就是forName。这种方式只要有名称即可,更为方便,扩展性更强。
package text;
public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException {
getClassObject_3();
}
//方式三
public static void getClassObject_3() throws ClassNotFoundException{ //抛出异常
String className="text.Person"; //注意这里的类名要包含包名,我将Person类自定义在包text下,所以前面要添加text.。否则“Person”会被视为一个字符串。
Class clazz=Class.forName(className);
System.out.println(clazz);
}
}
运行结果: