Java中的反射机制

什么是反射?
反射是一种可以在编译时获得解析类的能力。简单来说,通过反射可以直接创建对象、获得对象的属性、获得对象的方法…
反射的作用?
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的以及动态调用对象的方法的功能称为java语言的反射机制。
Java反射机制主要提供了以下功能:在运行时判定任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判定任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。
(以上来源百度)

1. 简单的例子:通过对象得到了包名及类名

package test1;
class X{}
public class GetClassNameDemo {
	public static void main(String[] args) {
		X x=new X();
		System.out.println(x.getClass().getName());
		}
}

2. 获得Class类的实例有三种方式

 - 通过"对象.getClass()"的方式获取该对象的Class实例。
 - 通过Class类的静态方法forName(),用类的全路径名获取一个Class实例。
 - 通过"类名.class"的方式来获取Class实例。

3. 通过反射创建对象(无参和有参)

无参

/**
* 无参
*/
package test1;
class Person{
	private String name;
	private int age;
	
	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;
	}
	public String toString() {
		return "姓名:"+this.name+",年龄:"+this.age;
	}

}
public class ReflectDemo01 {
	public static void main(String[] args)throws Exception {
		Class clazz=Class.forName("test1.Person"); //实例化Class对象
		Person p=(Person)clazz.newInstance(); //实现对象的实例化操作
		p.setAge(18);
		p.setName("中国");
		System.out.println(p);
		}
}

有参

  1. 通过Class类中的getConstructors()方法取得本类中的全部构造方法。
  2. 向构造方法中传递一个对象数组进去,里面包含构造方法中所需的各个参数。
  3. 通过Constructor实例化对象。
/**
*有参
*/
package test1;

import java.lang.reflect.Constructor;

class Person{
	private String name;
	private int age;
	public Person() {
		System.out.println("000000");
	}
	public Person(String name,int age) {
		System.out.println("111111");
	}
	public Person(String a,int b,double c) {
		System.out.println("222222");
	}
}
public class ReflectDemo01{
	public static void main(String[] args)throws Exception {
		Class clazz=Class.forName("test1.Person");
		Constructor cons[]=clazz.getConstructors();
		Person q=(Person)cons[0].newInstance();
		Person p=(Person)cons[1].newInstance("sd",18);
		Person r=(Person)cons[2].newInstance("sd",12,12);

		}
}

000000
111111
222222

特别要注意的是:当一个类中有多个构造方法时,在实例化的过程中要通过数组找到相应的方法,在上述案例中,**没有传递参数的Person作为类中的第一个构造方法,记为第0方法。**然后依次类推。
易得:

package test1;

import java.lang.reflect.Constructor;

class Person{
	private String name;
	private int age;
	public Person() {
		System.out.println("000000");
	}
	public Person(String a,int b,double c) {
		System.out.println("222222");
	}
	public Person(String name,int age) {
		System.out.println("111111");
	}

}
public class ReflectDemo01{
	public static void main(String[] args)throws Exception {
		Class clazz=Class.forName("test1.Person");
		Constructor cons[]=clazz.getConstructors();
		Person q=(Person)cons[0].newInstance();
		Person r=(Person)cons[1].newInstance("sd",12,12);
		Person p=(Person)cons[2].newInstance("sd",18);

		}
}

000000
222222
111111

当构造方法交换位置后,数组也发生了改变。

4. 通过反射访问属性

如果属性是私有的,则需要通过Filed类中的setAccessible()方法将需要操作的属性设置成可以被外界访问的。


 package test1;

import java.lang.reflect.Field;

class Person{
	private String name;
	private int age;
	public String toString() {
		return this.name+this.age;
	}
}
public class ReflectDemo01{
	public static void main(String[] args)throws Exception {
		Class clazz=Class.forName("test1.Person");
		Object p=clazz.newInstance();
		Field nameField=clazz.getDeclaredField("name");
		nameField.setAccessible(true);//开启访问权限 默认false
		nameField.set(p, "China");
		Field ageField=clazz.getDeclaredField("age");
		nameField.setAccessible(true);
		ageField.set(p, 20);
		System.out.println(p);
		}
}


5. 通过反射调用方法

通过getMethods()方法或getMethod()方法获取所有方法或指定方法/

package test1;

import java.lang.reflect.Method;

import web.ddddd;

class Person{
	private String name;
	private int age;
	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;
	}
	
	public String learn(String name,int age) {
		return "大家好,我是"+name+",今年"+age+"岁。";
	}
}
public class ReflectDemo01{
	public static void main(String[] args)throws Exception {
		Class clazz=Class.forName("test1.Person");
		Method md=clazz.getMethod("learn",String.class,int.class);
		String result=(String)md.invoke(clazz.newInstance(), "chinese",18);
		System.out.println(result);
		}
}


©️2020 CSDN 皮肤主题: 1024 设计师:上身试试 返回首页