反射详解 II

原创 2014年01月06日 18:57:23

一、反射获取成员字段

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


相关文章推荐

java反射机制&Annotation详解_II

简答的实现JDK动态代理和CGlib动态代理,非常容易学习
  • cjvs9k
  • cjvs9k
  • 2015年05月28日 14:34
  • 553

黑马程序员--Java基础加强--13.利用反射操作泛型II【TypeVariable】【GenericArrayType】【WildcardType】【Type及其子接口的来历】【个人总结】

利用反射操作泛型II-----  GenericArrayType接口          TypeVariable接口 WildcardType接口 Type及其及接口的来历 ---------...

uCOS-II源码详解

  • 2013年08月30日 11:28
  • 78KB
  • 下载

NIOS II常用函数详解

  • 2012年10月26日 09:29
  • 122KB
  • 下载

ucos_ii定时器详解

UCOSII从V2.83版本以后,加入了软件定时器,这使得UCOSII的功能更加完善,在其上的应用程序开发与移植也更加方便。在实时操作系统中一个好的软件定时器实现要求有较高的精度、较小的处理器开销,且...

TCPIP详解系列卷II.part2

  • 2009年06月18日 17:27
  • 7.94MB
  • 下载

TCP/IP 详解 (I/II卷英文版)

  • 2009年06月18日 00:27
  • 14.48MB
  • 下载

LeetCode Ugly Number i,ii详解

// Date : 2016.07.25 // Author : yqtao // https://github.com/yqtaowhu/**************************...

uCOS-II系统详解

  • 2016年10月20日 16:03
  • 1.5MB
  • 下载

NIOS II中文函数详解

  • 2012年01月26日 01:17
  • 605KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:反射详解 II
举报原因:
原因补充:

(最多只允许输入30个字)