关闭

反射详解 II

462人阅读 评论(0) 收藏 举报
分类:

一、反射获取成员字段

<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...


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:9323次
    • 积分:273
    • 等级:
    • 排名:千里之外
    • 原创:19篇
    • 转载:1篇
    • 译文:0篇
    • 评论:0条
    文章分类