`

用反射的方式获取父类中的所有属性和方法

阅读更多
package com.syh.jdbc.reflection_super;

/**
 * 父类
 * @author syh
 *
 */

public class Parent {

	public String publicField  = "1";
	
	String defaultField = "2"; 
	
	protected String protectedField = "3";
	
	private String privateField = "4" ;
	
	public void publicMethod() {
		System.out.println("publicMethod...");
	}
	
	void defaultMethod() {
		System.out.println("defaultMethod...");
	}
	
	protected void protectedMethod() {
		System.out.println("protectedMethod...");
	}
	
	private void privateMethod() {
		System.out.println("privateMethod...");
	}
	
}


package com.syh.jdbc.reflection_super;

/**
 * 子类
 * @author syh
 *
 */

public class Son extends Parent{

}



package com.syh.jdbc.reflection_super;

import java.lang.reflect.Field;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 方法类
 * @author syh
 *
 */

public class ReflectionUtils {

	/**
	 * 循环向上转型, 获取对象的 DeclaredMethod
	 * @param object : 子类对象
	 * @param methodName : 父类中的方法名
	 * @param parameterTypes : 父类中的方法参数类型
	 * @return 父类中的方法对象
	 */
	
	public static Method getDeclaredMethod(Object object, String methodName, Class<?> ... parameterTypes){
		Method method = null ;
		
		for(Class<?> clazz = object.getClass() ; clazz != Object.class ; clazz = clazz.getSuperclass()) {
			try {
				method = clazz.getDeclaredMethod(methodName, parameterTypes) ;
				return method ;
			} catch (Exception e) {
				//这里甚么都不要做!并且这里的异常必须这样写,不能抛出去。
				//如果这里的异常打印或者往外抛,则就不会执行clazz = clazz.getSuperclass(),最后就不会进入到父类中了
			
			}
		}
		
		return null;
	}
	
	/**
	 * 直接调用对象方法, 而忽略修饰符(private, protected, default)
	 * @param object : 子类对象
	 * @param methodName : 父类中的方法名
	 * @param parameterTypes : 父类中的方法参数类型
	 * @param parameters : 父类中的方法参数
	 * @return 父类中方法的执行结果
	 */
	
	public static Object invokeMethod(Object object, String methodName, Class<?> [] parameterTypes,
			Object [] parameters) {
		//根据 对象、方法名和对应的方法参数 通过反射 调用上面的方法获取 Method 对象
		Method method = getDeclaredMethod(object, methodName, parameterTypes) ;
		
		//抑制Java对方法进行检查,主要是针对私有方法而言
		method.setAccessible(true) ;
		
			try {
				if(null != method) {
					
					//调用object 的 method 所代表的方法,其方法的参数是 parameters
					return method.invoke(object, parameters) ;
				}
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			}
		
		return null;
	}

	/**
	 * 循环向上转型, 获取对象的 DeclaredField
	 * @param object : 子类对象
	 * @param fieldName : 父类中的属性名
	 * @return 父类中的属性对象
	 */
	
	public static Field getDeclaredField(Object object, String fieldName){
		Field field = null ;
		
		Class<?> clazz = object.getClass() ;
		
		for(; clazz != Object.class ; clazz = clazz.getSuperclass()) {
			try {
				field = clazz.getDeclaredField(fieldName) ;
				return field ;
			} catch (Exception e) {
				//这里甚么都不要做!并且这里的异常必须这样写,不能抛出去。
				//如果这里的异常打印或者往外抛,则就不会执行clazz = clazz.getSuperclass(),最后就不会进入到父类中了
				
			} 
		}
	
		return null;
	}	
	
	/**
	 * 直接设置对象属性值, 忽略 private/protected 修饰符, 也不经过 setter
	 * @param object : 子类对象
	 * @param fieldName : 父类中的属性名
	 * @param value : 将要设置的值
	 */
	
	public static void setFieldValue(Object object, String fieldName, Object value){
	
		//根据 对象和属性名通过反射 调用上面的方法获取 Field对象
		Field field = getDeclaredField(object, fieldName) ;
		
		//抑制Java对其的检查
		field.setAccessible(true) ;
		
		try {
			//将 object 中 field 所代表的值 设置为 value
			 field.set(object, value) ;
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		
	}
	
	/**
	 * 直接读取对象的属性值, 忽略 private/protected 修饰符, 也不经过 getter
	 * @param object : 子类对象
	 * @param fieldName : 父类中的属性名
	 * @return : 父类中的属性值
	 */
	
	public static Object getFieldValue(Object object, String fieldName){
		
		//根据 对象和属性名通过反射 调用上面的方法获取 Field对象
		Field field = getDeclaredField(object, fieldName) ;
		
		//抑制Java对其的检查
		field.setAccessible(true) ;
		
		try {
			//获取 object 中 field 所代表的属性值
			return field.get(object) ;
			
		} catch(Exception e) {
			e.printStackTrace() ;
		}
		
		return null;
	}
}



package com.syh.jdbc.reflection_super;

import static org.junit.Assert.*;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import org.junit.Test;

/**
 * 测试类,用JUnit4 进行测试
 * @author syh
 *
 */

public class ReflectionUtilsTest {

	/**
	 * 测试获取父类的各个方法对象
	 */
	
	@Test
	public void testGetDeclaredMethod() {
		
		Object obj = new Son() ;
		
		//获取公共方法名
		Method publicMethod = ReflectionUtils.getDeclaredMethod(obj, "publicMethod") ;
		System.out.println(publicMethod.getName());
		
		//获取默认方法名
		Method defaultMethod = ReflectionUtils.getDeclaredMethod(obj, "defaultMethod") ;
		System.out.println(defaultMethod.getName());
		
		//获取被保护方法名
		Method protectedMethod = ReflectionUtils.getDeclaredMethod(obj, "protectedMethod") ;
		System.out.println(protectedMethod.getName());
		
		//获取私有方法名
		Method privateMethod = ReflectionUtils.getDeclaredMethod(obj, "privateMethod") ;
		System.out.println(privateMethod.getName());
	}

	/**
	 * 测试调用父类的方法
	 * @throws Exception
	 */
	
	@Test
	public void testInvokeMethod() throws Exception {
		Object obj = new Son() ;
		
		//调用父类的公共方法
		ReflectionUtils.invokeMethod(obj, "publicMethod", null , null) ;
		
		//调用父类的默认方法
		ReflectionUtils.invokeMethod(obj, "defaultMethod", null , null) ;
		
		//调用父类的被保护方法
		ReflectionUtils.invokeMethod(obj, "protectedMethod", null , null) ;
		
		//调用父类的私有方法
		ReflectionUtils.invokeMethod(obj, "privateMethod", null , null) ;
	}

	/**
	 * 测试获取父类的各个属性名
	 */
	
	@Test
	public void testGetDeclaredField() {
		
		Object obj = new Son() ;
		
		//获取公共属性名
		Field publicField = ReflectionUtils.getDeclaredField(obj, "publicField") ;
		System.out.println(publicField.getName());
		
		//获取公共属性名
		Field defaultField = ReflectionUtils.getDeclaredField(obj, "defaultField") ;
		System.out.println(defaultField.getName());
		
		//获取公共属性名
		Field protectedField = ReflectionUtils.getDeclaredField(obj, "protectedField") ;
		System.out.println(protectedField.getName());
		
		//获取公共属性名
		Field privateField = ReflectionUtils.getDeclaredField(obj, "privateField") ;
		System.out.println(privateField.getName());
		
	}

	@Test
	public void testSetFieldValue() {
		
		Object obj = new Son() ;
		
		System.out.println("原来的各个属性的值: ");
		System.out.println("publicField = " + ReflectionUtils.getFieldValue(obj, "publicField"));
		System.out.println("defaultField = " + ReflectionUtils.getFieldValue(obj, "defaultField"));
		System.out.println("protectedField = " + ReflectionUtils.getFieldValue(obj, "protectedField"));
		System.out.println("privateField = " + ReflectionUtils.getFieldValue(obj, "privateField"));
		
		ReflectionUtils.setFieldValue(obj, "publicField", "a") ;
		ReflectionUtils.setFieldValue(obj, "defaultField", "b") ;
		ReflectionUtils.setFieldValue(obj, "protectedField", "c") ;
		ReflectionUtils.setFieldValue(obj, "privateField", "d") ;
		
		System.out.println("***********************************************************");
		
		System.out.println("将属性值改变后的各个属性值: ");
		System.out.println("publicField = " + ReflectionUtils.getFieldValue(obj, "publicField"));
		System.out.println("defaultField = " + ReflectionUtils.getFieldValue(obj, "defaultField"));
		System.out.println("protectedField = " + ReflectionUtils.getFieldValue(obj, "protectedField"));
		System.out.println("privateField = " + ReflectionUtils.getFieldValue(obj, "privateField"));
		
	}

	@Test
	public void testGetFieldValue() {
		
		Object obj = new Son() ;
		
		System.out.println("publicField = " + ReflectionUtils.getFieldValue(obj, "publicField"));
		System.out.println("defaultField = " + ReflectionUtils.getFieldValue(obj, "defaultField"));
		System.out.println("protectedField = " + ReflectionUtils.getFieldValue(obj, "protectedField"));
		System.out.println("privateField = " + ReflectionUtils.getFieldValue(obj, "privateField"));
	}

}


分享到:
评论
8 楼 leyen 2016-06-24  
茅塞顿开,THANK YOU!
7 楼 leyen 2016-06-24  
所有的类都继承自Object
mengshixian 写道
如果是没有父类了,是不是要出错了
怎么判断类有没有父类

6 楼 sunshine_bean 2015-05-14  
这个直接调用getMethod也可以的,就不用这些封装了
5 楼 hety163 2015-03-27  
太厉害了
4 楼 396063616 2013-06-20  
如果有三个类  A , B , C
A: 有 public void getId(); 方法。
B: 有 private A a=new A(); 属性。
C: 继承 B 。

当我通过反射机制获得 B 类中的 private A a; 属性后,再想调用 A 类里的 getId() 方法,怎么做呢?
3 楼 pdw2009 2012-11-28  
不错,直接拿 来用了
2 楼 rzhzhz 2011-08-30  
mengshixian 写道
如果是没有父类了,是不是要出错了
怎么判断类有没有父类

怎么会没有父类呢,就算不声明也是Object的子类
1 楼 mengshixian 2011-08-01  
如果是没有父类了,是不是要出错了
怎么判断类有没有父类

相关推荐

    java反射操作父类所有属性和方法

    java的反射机制操作父类的所有属性和方法。

    java反射获取所有属性,获取所有get方法,包括子类父类

    java反射获取所有属性,获取所有get方法,包括子类父类,以及包括List集合类

    java反射机制学习(三):通过反射获取实体类的属性、方法、接口和父类信息

    NULL 博文链接:https://1017401036.iteye.com/blog/2343706

    基础深化和提高-java反射技术

    通过反射,程序可以在运行时检查类、实例化对象、调用方法、获取和设置属性,甚至可以动态修改类的结构。 Java反射技术的核心在于java.lang.reflect包,它提供了一系列类和接口,用于在运行时获取关于类和对象的...

    常见的java面试题及解答

    继承允许子类继承父类的方法和属性,同时可以重写父类的方法,从而实现多态。接口则允许不同的类通过实现同一个接口来达到多态的效果。 Java中如何避免空指针异常? 在Java中,可以通过对可能为空的对象进行“非空...

    Java反射机制重点总结

    文章目录Java ReflectionJava反射机制提供的功能Java反射相关的主要API...反射调用类的完整结构获取实现的全部接口获取所继承的父类获取全部的构造器获取全部的方法获取全部的属性获取Annotation相关获取泛型相关获取...

    【十六】Java反射(了解单例、用工厂模式去创建对象,它不香吗?)

    类对象: 类加载的产物,封装了一个类的所有信息(类名、父类、接口、属性、方法、构造方法) 二、获取类对象的方法 通过类的对象,获取类对象 Person p = new Person(); Class c = p.getClass(); 通过类名获取类...

    JAVA面试题最全集

    将变量或方法声明为final,可以保证它们在使用中不被改变。被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改。被声明为final的方法也同样只能使用,不能重载 finally?再异常处理时...

    net学习笔记及其他代码应用

    Abstract 类的子类为它们父类中的所有抽象方法提供实现,否则它们也是抽象类为。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。 接口(interface)是抽象类的变体。在接口中,所有方法...

    Java开发技术大全(500个源代码).

    DumpMethods.java 使用反射机制来获取类中的方法 getClassName.java 利用反射机制获取类的名字 invokeConstructor.java 利用反射机制调用构造器 invokeMethod.java 利用反射机制调用成员方法 listConstructors....

    Java开发技术大全 电子版

    9.6利用反射获取运行时类信息293 9.6.1使用isInstance()方法判断所属类294 9.6.2获取成员方法信息295 9.6.3获取构造方法信息296 9.6.4获取类的成员属性297 9.6.5根据方法的名称来执行方法299 9.6.6创建新的...

    疯狂JAVA讲义

    6.8.3 枚举类的属性、方法和构造器 220 6.8.4 实现接口的枚举类 223 6.8.5 包含抽象方法的枚举类 224 6.9 对象与垃圾回收 225 6.9.1 对象在内存中的状态 226 6.9.2 强制垃圾回收 227 6.9.3 finalize方法 228 ...

    JAVA反射之类对象

     类对象:类加载的产物,封装了一个类的所有信息(类名、父类、接口、属性、方法、构造方法) 获取类对象: 通过类的对象,获取类对象 Student s = new Student(); Class c = s.getClass(); 通过类名获取类对象 ...

    Java开发实战1200例(第1卷).(清华出版.李钟尉.陈丹丹).part3

    实例099 重写父类中的方法 121 实例100 计算几何图形的面积 122 实例101 提高产品质量的方法 123 实例102 简单的汽车销售商场 124 5.5 Object类的应用 126 实例103 两只完全相同的宠物 126 实例104 简化equals()方法...

    python入门到高级全栈工程师培训 第3期 附课件代码

    11 在子类中调用父类方法 12 super调用父类的方法 13 选择系统作业讲解 第26章 01 学生自主复习 02 分享列表 03 多态 04 封装 05 面向对象概念总结 06 反射 07 反射及动态导入模块 08 类的内置attr属性 09 类内置...

    \java超强笔记(超级经典)

    静态方法可以是泛型方法(在修饰符和返回值之间写泛型),但是不可以使用类的泛型。 static void copyArrayToList(Object[] os,List&lt;T&gt; ls){ //错误,T为类的泛型 } static &lt;E&gt; void ...

Global site tag (gtag.js) - Google Analytics