Java中的反射机制


  • JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性。这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

一、反射机制之Class

  • 代表类的实体,在运行的Java应用程序中表示类和接口。

1.获取Class

  • ① 类型.class
    Class<User> userClass = User.class;
    
  • ② Class.forName(“完整类名”)
    • 这种方式类加载,静态代码块执行
    Class userClass = Class.forName("User");
    
  • ③ 任何对象.getClass()
    //创建一个User对象
    User user = new User("root", "123456");
    Class<? extends User> userClass = user.getClass();
    
  • 常用方法
    getPackage();//获取类的包
    getName();//获取类的完整路径名字
    getSimpleName();//获取类的名字
    getSuperclass();//获取当前类继承的父类的名字
    

二、反射机制之Constructor

  • 代表类的构造方法。

1.获取Constructor

public Constructor<T> getConstructor(Class<?>... parameterTypes);//获得该类中与参数类型匹配的公有构造方法
public Constructor<?>[] getConstructors();//获得该类的所有公有构造方法
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes);//获得该类中与参数类型匹配的构造方法
public Constructor<T> getDeclaredConstructor();//获得该类所有构造方法

2.使用Constructor实例化对象

newInstance(Object... initargs);//根据传递的参数创建类的对象

三、实例化对象

  • userClass.newInstance(),这种方式必须确保无参数构造方法存在。
  • userClass.getDeclaredConstructor().newInstance()

四、反射机制之Method

  • 代表类的方法

1.获取Method

  • 要获取方法Method,首先你需要获取这个类Class
  • 当拿到Class之后,调用Class的方法可以获取到对象的方法。
    • 获取一个方法,需要告诉Java程序,你要获取的方法名字是什么,这个方法上每个形参的类型是什么。这样Java程序才能给你拿到对应的方法。
    • 这样的设计也非常合理,因为一个类当中,方法是支持重载的,也就说方法名可以一样,但参数列表一定是不一样的,所以获取一个方法需要提供方法名以及每个形参的类型。
    /**
    * 四个方法中,不带Declared的方法能获取自身类和父类的所有public方法。带Declared的方法能获取自身所有方法但不能获取父类中的方法。
    * 只有通过方法签名才能找到唯一的方法,方法签名=方法名+参数列表(参数类型、参数个数、参数顺序)。
    * 只能获取父类中的public方法,无法获取到父类的默认权限和private权限方法
    */
    public Method getDeclaredMethod(String name, Class<?>... parameterTypes);//表示调用指定的一个本类中的方法(不包括继承的)
    public Method[] getDeclaredMethods();//获取自身所有的方法(不包括继承的和访问权限无关)。
    public Method[] getMethods();//获取包括自身和继承过来的所有的public方法。
    public Method getMethod(String methodName, Class<?>...parameterTypes);//表示调用指定的一个public方法(包括继承的)
    

2.调用方法

  • 调用一个方法,一般涉及到四个要素:
    • ① 调用哪个对象的。
    • ② 哪个方法。
    • ③ 传什么参数。
    • ④ 返回什么值。
  • 调用方法的三步骤:
    • ① 创建对象(四要素之首:调用哪个对象的)
    • ② 获取方法(四要素之一:哪个方法)
    • ③ 调用方法
/**
* obj参数:表示调用方法底层所属对象。
* args参数:表示调用方法传递的实际参数。
* 返回值:底层方法的返回值。
*/
public Object invoke(Object obj, Object... args);//表示调用当前Method表示的方法。

(1)调用私有方法

  • 在调用私有方法之前:应该设置该方法为可访问的。
  • 因为 MethodAccessibleObject的子类,所以Method中具有方法:setAccessible(true)

(2)调用静态方法

  • 如果底层是静态方法,那么可以忽略指定的 obj 参数。将 obj 参数设置为 null 即可。
  • 也可以将 obj 参数写上也没有影响。

(3)调用可变参数方法

  • 对于数组类型的引用类型的参数,底层会自动解包,为了解决该问题,我们使用 Object 的一维数组把实际参数包装起来。

    method.invoke(null, new Object[]{"username", "password"});
    
  • (牢记)以后使用反射调用invoke方法,在传递实际参数的时候,无论是基本数据类型还是引用数据类型,也无论是可变参数类型,反正就是一切实际参数都包装在new Object[]{}中,就没问题。


五、反射机制之Field

  • 代表类的成员变量(成员变量也称为类的属性)。

1.获取Field

public Field getDeclaredField(String name);//表示调用指定的一个本类中的属性(不包括继承的)
public Field[] getDeclaredFields();//获取自身所有的属性(不包括继承的和访问权限无关)。
public Field[] getFields();//获取包括自身和继承过来的所有的public属性。
public Field getField(String name);//表示调用指定的一个public属性(包括继承的)

2.使用Field

public void set(Object obj, Object value);//设置obj中对应属性值
public Object get(Object obj);//获得obj中对应的属性值
public boolean equals(Object obj);//属性与obj相等则返回true 

六、反射的应用案例

1.用反射来遍历对象中的属性

  • 使用反射来进行遍历对象中的所有属性名和属性值。在遍历中编写逻辑来对属性进行操作。
public static void main(String[]args) throws Exception {
	//创建一个User对象
	User user = new User("root", "123456");
	//通过getDeclaredFields()方法获取对象类中的所有属性(含私有)
	Field[] fields = user.getClass().getDeclaredFields();

	//遍历属性
	for (Field field : fields) {
		//通过setAccessible()设置为true,允许通过反射访问私有变量
		field.setAccessible(true);

		//获取属性值
		Object value = field.get(user);
		//获取属性名
		String name = field.getName();

		//输出到控制台
		System.out.println("属性名:"+name+" 值:"+value);
		
		// 其他操作...
	}
}

这个兄弟写的挺好可以参考 ===> Java反射的原理及反射创建类实例的三种方式


  • 40
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小宝945

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值