RefFieldMethodDetails——查看类的域和方法

本文详细介绍了如何通过反射机制获取Java类的域、方法及构造函数,并展示了方法覆盖的不同场景。通过实例代码演示了完全覆盖和不完全覆盖的情况,以及桥方法的作用。

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

RefFieldMethodDetails,通过反射机制查看类的域和方法(包括编译器添加的“桥方法”)

public class RefFieldMethodDetails {
	
	/**
	 * 打印出指定类的
	 * 1、声明的所有构造方法(包括私有)
	 * 2、声明的所有方法(包括私有)
	 * 3、声明的所有域(包括私有)
	 */
	public static <T> void details(Class<T> clazz){
		details(clazz.getName());
	}
	
	/**
	 * 打印出指定类的
	 * 1、所有公共构造方法(包括超类)
	 * 2、所有公共方法(包括超类)
	 * 3、所有公共域(包括超类)
	 */
	public static <T> void details2(Class<T> clazz){
		details2(clazz.getName());
	}
	
	/**
	 * 打印出指定类的
	 * 1、声明的所有构造方法(包括私有)
	 * 2、声明的所有方法(包括私有)
	 * 3、声明的所有域(包括私有)
	 */
	public static void details(String name){
		try {
			Class cl = Class.forName(name);
			Class supercl = cl.getSuperclass();
			
			String modifiers = Modifier.toString(cl.getModifiers());
			if(modifiers.length()>0){
				System.out.print(modifiers + " ");
			}
			System.out.print("class " + name);
			if(supercl !=null && supercl!=Object.class){
				System.out.print(" extends " + supercl.getName());
			}
			
			System.out.print("\n{\n");
			printConstructors(cl);
			System.out.println();
			printMethods(cl);
			System.out.println();
			printFields(cl);
			System.out.println("}");
			
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	/**
	 * 打印出指定类的
	 * 1、所有公共构造方法(包括超类)
	 * 2、所有公共方法(包括超类)
	 * 3、所有公共域(包括超类)
	 */
	public static void details2(String name){
		try {
			Class cl = Class.forName(name);
			Class supercl = cl.getSuperclass();
			
			String modifiers = Modifier.toString(cl.getModifiers());
			if(modifiers.length()>0){
				System.out.print(modifiers + " ");
			}
			System.out.print("class " + name);
			if(supercl !=null && supercl!=Object.class){
				System.out.print(" extends " + supercl.getName());
			}
			
			System.out.print("\n{\n");
			printConstructors2(cl);
			System.out.println();
			printMethods2(cl);
			System.out.println();
			printFields2(cl);
			System.out.println("}");
			
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	//返回本类声明的所有域(包括私有)
	private static void printFields(Class cl) {
		Field[] fields = cl.getDeclaredFields();
		for(Field field : fields){
			String modifier = Modifier.toString(field.getModifiers());
			Class type = field.getType();
			String name = field.getName();
			System.out.print("  ");
			System.out.print(modifier +" ");
			System.out.print(type + " ");
			System.out.println(name + ";");
		}
		
	}
	//返回本类的所有公共域(包括超类)
	private static void printFields2(Class cl) {
		Field[] fields = cl.getFields();
		for(Field field : fields){
			String modifier = Modifier.toString(field.getModifiers());
			Class type = field.getType();
			String name = field.getName();
			System.out.print("  ");
			System.out.print(modifier +" ");
			System.out.print(type + " ");
			System.out.println(name + ";");
		}
		
	}
	
	//返回本类声明的所有方法(包括私有)
	private static void printMethods(Class cl) {
		Method[] methods = cl.getDeclaredMethods();
		for(Method method : methods){
			String modifier = Modifier.toString(method.getModifiers());
			Class returnType = method.getReturnType();
			String name = method.getName();
			Class[] params = method.getParameterTypes();
			
			System.out.print("  ");
			if(modifier.length()>0){
				System.out.print(modifier + " ");
			}
			System.out.print(returnType.getSimpleName() +" ");
			System.out.print(name+"( ");
			for(int i=0;i<params.length;i++){
				System.out.print(params[i].getName());
				if(i!=params.length-1){
					System.out.print(", ");
				}
			}
			System.out.println(" );");
		}
		
	}
	//返回本类的所有公共方法(包括超类)
	private static void printMethods2(Class cl) {
		Method[] methods = cl.getMethods();
		for(Method method : methods){
			String modifier = Modifier.toString(method.getModifiers());
			Class returnType = method.getReturnType();
			String name = method.getName();
			Class[] params = method.getParameterTypes();
			
			System.out.print("  ");
			if(modifier.length()>0){
				System.out.print(modifier + " ");
			}
			System.out.print(returnType.getSimpleName() +" ");
			System.out.print(name+"( ");
			for(int i=0;i<params.length;i++){
				System.out.print(params[i].getName());
				if(i!=params.length-1){
					System.out.print(", ");
				}
			}
			System.out.println(" );");
		}
		
	}

	//返回本类声明的所有构造方法(包括私有)
	private static void printConstructors(Class cl) {
		Constructor[] cs = cl.getDeclaredConstructors();
		for(Constructor c : cs){
			String modifier = Modifier.toString(c.getModifiers());
			String name = c.getName();
			Class[] params = c.getParameterTypes();
			
			System.out.print("  ");
			if(modifier.length()>0){
				System.out.print(modifier + " ");
			}
			System.out.print(name);
			System.out.print("( ");
			for(int i=0 ;i<params.length ;i++){
				System.out.print(params[i].getName());
				if(i!=params.length-1){
					System.out.print(", ");
				}
			}
			System.out.println(" );");
			
		}
		
	}
	//返回本类的所有公共构造方法(包括超类)
	private static void printConstructors2(Class cl) {
		Constructor[] cs = cl.getConstructors();
		for(Constructor c : cs){
			String modifier = Modifier.toString(c.getModifiers());
			String name = c.getName();
			Class[] params = c.getParameterTypes();
			
			System.out.print("  ");
			if(modifier.length()>0){
				System.out.print(modifier + " ");
			}
			System.out.print(name);
			System.out.print("( ");
			for(int i=0 ;i<params.length ;i++){
				System.out.print(params[i].getName());
				if(i!=params.length-1){
					System.out.print(", ");
				}
			}
			System.out.println(" );");
			
		}
	}
}

对程序员来说,方法的签名只包括:

1、方法的名称;2、参数的类型;3、参数的顺序;

但是对JVM而言,方法的签名还包括:4、返回的类型!


演示“完全” Override,即上述4 条件都满足:

class SuperClass{
	private final String name;

	public SuperClass(String name) {
		super();
		this.name = name;
	}

	public String getName() {
		return "SuperClass";
	}
	
}

public class OverrideTest extends SuperClass{
	private final Date date;

	public OverrideTest(String name, Date date) {
		super(name);
		this.date = date;
	}

	public Date getDate() {
		return date;
	}
	
	//覆盖父类的方法,重点是这个
	@Override
	public String getName() {
		return "OverrideTest";
	}
}
通过 RefFieldMethodDetails,来查看OverrideTest 类的域和方法:

	@Test
	public void testGetName() {
		RefFieldMethodDetails.details(OverrideTest.class);
		
		RefFieldMethodDetails.details2(OverrideTest.class);
	}

这和我们理解的“覆盖”相吻合!即,始终只有一个方法签名的方法。

下面来看看,“不完全”覆盖,即参数类型是继承关系(泛型的特殊处理,一般情况是重载)返回类型不同时的情况:

class Pair<T> {

	private T first;
	private T second;

	public Pair() {
		first = null;
		second = null;
	}
	
	public Pair(T first, T second) {
		this.first = first;
		this.second = second;
	}

	public T getFirst() {
		return first;
	}

	public T getSecond() {
		return second;
	}

	public void setFirst(T newValue) {
		first = newValue;
	}

	public void setSecond(T newValue) {
		second = newValue;
	}
}

public class DateInterval extends Pair<Date>{
	
	//参数类型——有继承关系
	@Override
	public void setSecond( Date second ){
		if( second.compareTo( getFirst()) >= 0 ){
			super.setSecond( second );
		}
	}
	
	//返回类型不同
	@Override
	public Date getSecond(){
		return (Date)super.getSecond();
	}
}

通过 RefFieldMethodDetails,来查看 DateInterval 类的域和方法:

	@Test
	public void testOverride() {
		
		//打印DateInterval 的所有域和方法(包括private 不包括父类的)
		RefFieldMethodDetails.details( DateInterval.class );

		//打印DateInterval 的所有公共域和方法(包括父类的)
		RefFieldMethodDetails.details2( DateInterval.class );
	}

“桥方法”的任务就是调用子类相应的“不完全”覆盖的方法。

常用的“桥方法”实现有,clone 方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值