反射的一点小应用

     今天工作中遇到这样一种情况,有一个父类,下面有非常多各种各样的子类,同时有这样一个总类,它包含了前面说的子类的所有属性,同时还拥有一个属性type标志它对应前面说的子类内容。这个总类实例要和前面的一堆子类实例进行比较,那堆子类是挂在List<父类>下的,比较时总类要根据type找到对应的子类对象,才可以比较。文字不好说明,看下面的代码(类似工作中遇到的情形)。


package com.fei;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class WifeFindHusband {

	public static void main(String[] args) {
		//TallHusband/FatHusband的父类是Husband
		List<Husband> husbands = new ArrayList<Husband>();
		//public TallHusband(String name, String secondName)
		husbands.add(new TallHusband("李明","狗娃"));
		//public FatHusband(String name, int age)
		husbands.add(new FatHusband("张华",18));
		
		//public Wife(String name, String husbandType, String husbandName,String husbandSecondName, int husbandAge)
		List<Wife> wifes = new ArrayList<Wife>();
		wifes.add(new Wife("陈红","tall","李明","狗娃",0));
		wifes.add(new Wife("林丽","fat","张华","",25));
		//妻子找丈夫,tall 对于 TallHusband,fat 对于 FatHusband
		//先判断丈夫类型,在详细比较
		find1(wifes,husbands);
		find2(wifes,husbands);
//		Husband h = new TallHusband("李明","狗娃");
//		TallHusband th = TallHusband.class.cast(h);
	}
	/**缺点: 如果丈夫类型有非常多(Husband的子类特别多),则if else if的判断会非常多
	 *有新类型的丈夫加入时,该方法需要修改它,多加else if判断
	 *优点:类型转换有保证,掉用CompatorHelper时,编译期就能准确知道调用哪个方法
	 */
	private static void find1( List<Wife> wifes ,List<Husband> husbands){
		for(Wife wife : wifes){
			boolean isFind = false;
			for(Husband husband : husbands){
				if("tall".equals(wife.getHusbandType()) && husband instanceof TallHusband){
					isFind =CompatorHelper. isCouple(wife,TallHusband.class.cast(husband));
				}else if("fat".equals(wife.getHusbandType()) && husband instanceof FatHusband){
					isFind = CompatorHelper.isCouple(wife,(FatHusband)husband);
				}
				if(isFind) break;
			}
			if(isFind){
				System.out.println("妻子"+wife.getName()+"找到丈夫了");
			}else{
				System.out.println("妻子"+wife.getName()+"没到丈夫了");
			}
				
		}
	}
	
	private static Map<String,Class<? extends Husband>> HUSBAND_TYPE;
	static{
		HUSBAND_TYPE = new HashMap<String,Class<? extends Husband>>();
		HUSBAND_TYPE.put("tall", TallHusband.class);
		HUSBAND_TYPE.put("fat", FatHusband.class);
	}
	/**
	 * 优点:当有新丈夫类型加入时,只需HUSBAND_TYPE中增加配置即可,不需要修改find2方
	 * 缺点:调用CompatorHelper中的方法时,无法在编译期就能检查到是否存在
	 */
	private static void find2( List<Wife> wifes ,List<Husband> husbands){
		for(Wife wife : wifes){
			boolean isFind = false;
			Class<? extends Husband> husbandType = HUSBAND_TYPE.get(wife.getHusbandType());
			if(husbandType != null){
				for(Husband husband : husbands){
					if(husbandType == husband.getClass()){
						//无法用这中形式,因为编译期无法确定husbandType.cast(husband)的具体类型,编译器报错
						//所以考虑用反射,突破编译器的约束
		//				isFind = CompatorHelper.isCouple(wife, husbandType.cast(husband));
						try {
						Method m=	CompatorHelper.class.getMethod("isCouple",wife.getClass(), husbandType);
						isFind =(boolean) m.invoke(null,wife,husband);
						} catch (Exception e) {
							e.printStackTrace();
							throw new RuntimeException("妻子找丈夫报错,CompatorHelper类isCouple方法无"+husbandType.getName()+"这种类型的丈夫");
						}
					}
					if(isFind) break;
				}
			}
			if(isFind){
				System.out.println("妻子"+wife.getName()+"找到丈夫了");
			}else{
				System.out.println("妻子"+wife.getName()+"没到丈夫了");
			}
				
		}
		
	}
	
}

package com.fei;

public class CompatorHelper {

	public static boolean isCouple(Wife wife ,TallHusband husband){
		if(wife.getHusbandName().equals(husband.getName())
				&& wife.getHusbandSecondName().equals(husband.getSecondName())){
			return true;
		}
		return false;
	}
	public static boolean isCouple(Wife wife ,FatHusband husband){
		if(wife.getHusbandName().equals(husband.getName())
				&& wife.getHusbandAge() == husband.getAge()){
			return true;
		}
		return false;
	}
}

      想了想,还是倾向于用find1方法,虽然会有很多if else if的判断,但是对CompatorHelper的调用可以在编译期就可以保证必须有对应的方法。如果用find2方法,由于哟哦那个了反射,如果CompatorHelper缺少了某些方法,在编译期也不报错,在运行期才会报错,风险较大,除非测试充分,把所有的丈夫类型都测试一遍。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值