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'}
原文地址:https://www.cnblogs.com/cgl-dong/p/12157678.html