反射详解 II

本文详细介绍了Java反射机制,包括如何通过反射获取类的成员字段和成员方法。讲解了getFields()、getDeclaredFields()、getField()、getDeclaredField()等方法的使用,以及在操作私有成员时可能遇到的问题和解决方案。同时,还讨论了如何通过Method类对象调用成员方法,特别提到了对私有方法的操作及其注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、反射获取成员字段

<1>Filed类:代表了类中的一个成员变量

   1、得到一个类中的所有成员变量:

   (1)所有公共成员(public)变量:getFields();

   (2)所有声明过(任意权限)的成员变量:getDeclaredFields();

   (3)获取指定的public成员变量:getField(Stringname)

   (4)获取指定的任意权限的成员变量:getDeclaredField(Stringname)

获取成员变量的实体类对象:

public class Student {
	public String name;
	private int age;
	int height;
	protected String sex;
}

【1】   Class类的getFields()方法

Class clazz = Class.forName("com.jtt.demo.Student");
		Field[] fields = clazz.getFields();
		for (Field f : fields) {
			System.out.println(f);
		}

输出结果:public java.lang.String com.jtt.demo.Student.name

只获取公共成员变量

【2】getDeclaredFields()方法

Class clazz = Class.forName("com.jtt.demo.Student");
		Field[] fields = clazz.getDeclaredFields();
		for (Field f : fields) {
			System.out.println(f);
		}

输出结果:

public java.lang.Stringcom.jtt.demo.Student.name

private intcom.jtt.demo.Student.age

int com.jtt.demo.Student.height

protected java.lang.Stringcom.jtt.demo.Student.sex

输出了所有申明成员变量

<2>调用Field类对象的set/get方法来操作对应的字段

其中需要注意的是操作不同权限成员变量,尤其是private

其中:

Class clazz = Class.forName("com.jtt.demo.Student");
		Field field = clazz.getField("age");// age不是public
		Object obj = clazz.newInstance();// 实例化
		field.set(obj, 25);
		System.out.println(field.get(obj));

输出结果:java.lang.NoSuchFieldException: age

原因:age为private类型字段,而getField只能获取public类型字段,故没有获取到这个字段,

这时候我们自然而然的会想起用getDeclaredField()方法

但是还是会报错,不过跟之前的不同

输出结果:java.lang.IllegalAccessException:

Class com.jtt.jdk5.ClassDemo can not access amember of class com.jtt.demo.Student with modifiers "private"

原因:因为age为private类型字段,不能直接操作

解决方法:使用getDeclaredField( )+ 取消对反射对象进行访问权限检查机制操作非public字段

Class clazz = Class.forName("com.jtt.demo.Student");
       Field field = clazz.getDeclaredField("age");// age不是public,用getDeclaredField可获取
       // 取消对反射对象进行访问权限检查机制
       field.setAccessible(true);
       Object obj = clazz.newInstance();// 实例化
       field.set(obj, 25);
       System.out.println(field.get(obj));
输出结果: 25
二、放射获取成员方法

跟获取成员变量方法类似

<1> Method:代表了类中的一个成员方法

   1、得到一个类中的所有成员方法

   (1)所有公共成员(public)方法:getMethods();

   (2)所有声明过(任意权限)的成员方法:getDeclaredMethods();

  (3)获取指定的public成员方法

    getMethod(Stringname,Class<?>…parameterTypes)

  (4)获取指定的任意权限的成员方法:

    getDeclaredMethod(String name,Class<?>…)

获取成员方法的实体类对象:
public class Student {
	private int age;
	private String name;

	public void method() {
		System.out.println("method run...");
	}

	private void method2() {
		System.out.println("method2 run...");
	}
public void paramMethod(String name, int age) {
		System.out.println(name + "paramMethod run..." + age);
	}
  【1】     Class类 getMethods() 方法
Class clazz = Class.forName("com.jtt.demo.Student");
		Method[] methods = clazz.getMethods();
		for (Method method : methods) {
			System.out.println(method);
		}

输出结果:

public void com.jtt.demo.Student.paramMethod(java.lang.String,int)

public void com.jtt.demo.Student.method()

public final native java.lang.Class java.lang.Object.getClass()

public native int java.lang.Object.hashCode()

public boolean java.lang.Object.equals(java.lang.Object)

public java.lang.String java.lang.Object.toString()

public final native void java.lang.Object.notify()

public final native void java.lang.Object.notifyAll()

public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException

public final void java.lang.Object.wait() throws java.lang.InterruptedException

public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException

只获取公共的成员方法,【注意】也包含父类public方法

2getDeclaredFields()方法

Class clazz = Class.forName("com.jtt.demo.Student");
		Field[] fields = clazz.getDeclaredFields();
		for (Field f : fields) {
			System.out.println(f);
		}

输出结果:

private void com.jtt.demo.Student.method2()

public void com.jtt.demo.Student.paramMethod(java.lang.String,int)

public void com.jtt.demo.Student.method()

输出了所有申明的成员方法;【注意】不包含父类的方法,仅仅包含子类任意访问权限的方法

<2>调用Method类对象的invoke方法来调用指定的方法

其中需要注意的是操作不同权限成员方法

[1]. 操作公有public字段类对象

1反射调用无参方法

 Class clazz = Class.forName("com.jtt.demo.Student");
		Object obj = clazz.newInstance();
		Method method = clazz.getMethod("method", null);
   		method.invoke(obj, null);

2反射调用有参方法

Class clazz = Class.forName("com.jtt.demo.Student");
		Object obj = clazz.newInstance();

		Method method = clazz.getMethod("paramMethod", String.class, int.class);
		method.invoke(obj, "lisi", 25);

[2]. 操作公有public字段类对象

其中:

Class clazz = Class.forName("com.jtt.demo.Student");
		Object obj = clazz.newInstance();

		Method method = clazz.getMethod("method2",null);
		method.invoke(obj, null);

输出结果:

java.lang.NoSuchMethodException: com.jtt.demo.Student.Method2()

原因:Method2()private类型方法,而getMethod只能获取public类型字段,故没有获取到这个方法,

这时候我们自然而然的会想起用getDeclaredMethod()方法

Class clazz = Class.forName("com.jtt.demo.Student");
		Object obj = clazz.newInstance();

		Method method = clazz.getDeclaredMethod("method2", null);
		method.invoke(obj, null);

但是还是会报错,不过跟之前的不同

输出结果: java.lang.IllegalAccessException

Class com.jtt.jdk5.ClassDemo can not access a member of class com.jtt.demo.Student with modifiers "private"

原因:因为method2private类型方法,不能直接操作


解决方法:使用getDeclaredMethod( )+ 取消对反射对象进行访问权限检查机制 操作非public方法

Class clazz = Class.forName("com.jtt.demo.Student");
		Object obj = clazz.newInstance();

		Method method = clazz.getDeclaredMethod("method2", null);
		// 指示JVM取消对访问权限的检查
		method.setAccessible(true);
		method.invoke(obj, null);

输出结果method2 run...


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值