Java反射
Java反射
反射是Java的高级特性,让原本是静态类型的Java拥有了动态语言的特点。
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。
就像镜子一样,反射回来的画面和原本的物体一样。
反射是Java的重要特性,Java的Spring框架底层就基于反射。
Class类
Java中反射的实现是通过Class类表示的,只要获取到Class的对象实例,就可以拿到类的所有信息。
Class类代表字节码,处于java.lang.reflect
包下。
反射包下包含所有与反射有关的类,如java.lang.reflect.Field
每个类都会在jvm中编译成字节码,jvm在加载类时对每个对象都会生成一个Class对象,该对象能够在运行时获得类的所有信息,如构造方法、属性、超类等。
一个类在 JVM 中只会有一个Class实例。
获取Class对象的三种方法
/**
\* 获取Class对象的三种方式
\* 1 Object ——> getClass();
\* 2 任何数据类型(包括基本数据类型)都有一个“静态”的class属性
\* 3 通过Class类的静态方法:forName(String className)(常用)
*/
建立包reflects
,在包下创建父类Person,子类Man.
class Person{
String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "{" +
" name='" + getName() + "'" +
"}";
}
}
class Man extends Person{
private int age;
public Man(String name,int age) {
super(name);
this.age=age;
}
@Override
public String toString() {
return "Man [age=" + age + ", name=" + name + "]";
}
}
在主方法中测试Class对象。
1、通过对象的getClass()方法获取Class对象,该方法是Object类下的方法
public static void main(String[] args) throws Exception {
//通过对象的getClass()方法获取Class对象,该方法是Object类下的方法
Man man=new Man("张三",8);
Class c1=man.getClass();
//打印Class对象
System.out.println(c1);//class reflects.Man
System.out.println(c1.getName());//reflects.Man
System.out.println(c1.getSimpleName());//Man
System.out.println(c1.getTypeName());//reflects.Man
//获取public构造函数数组
System.out.println(c1.getConstructors()[0]);//public reflects.Man(java.lang.String,int)
//获取超类
System.out.println(c1.getSuperclass());//class reflects.Person
//获取private字段数组
Field[] f=c1.getDeclaredFields();
for(Field f0:f) {
System.out.println(f0);//private int reflects.Man.age
}
}
2、通过“静态”的class属性获取Class对象
//通过“静态”的class属性获取Class对象
Class c2=Man.class;
System.out.println(c2);//class reflects.Man
3、通过Class类的静态方法:forName(String className)(常用)
//通过Class类的静态方法:forName(String className)(常用)
Class c3=Class.forName("reflects.Man");
System.out.println(c3);//class reflects.Man
Class对象的实例只有一个,各种方式获取的都是同一个对象。
通过hashCode()方法测试。
System.out.println(c1.hashCode());//31168322
System.out.println(c2.hashCode());//31168322
System.out.println(c3.hashCode());//31168322
//通过hashCode可以看出三种方法生成的对象时同一个
System.out.println(c1==c2);//true
System.out.println(c1.equals(c3));//true
测试
测试通过反射创建对象,并且修改方法。
Constructor con= c1.getConstructor(String.class,int.class);//获取构造器对象
Man man2=(Man)con.newInstance("jim",10);//通过构造器对象创建实例
System.out.println(man2);
//Man [age=10, name=jim]
Class c4=c1.getSuperclass();//获取超类
Constructor p=c4.getConstructor(String.class);
Person person=(Person)p.newInstance("hon");
System.out.println(person);
Method method= c4.getDeclaredMethod("setName", String.class);//获取方法对象
method.invoke(person, "Tony");//激活方法修改器
System.out.println(person);
//{ name='hon'}
//{ name='Tony'}