我需要对不确定类型的对象进行操作,我知道它可以采用哪种类型,但是我无法控制这些类型。我无法修改A,B,..类
有没有比以下更好的解决方案:
if (obj instanceof A)
return extractA((A) obj);
if (obj instanceof B)
return extractB((B) obj);
....
谢谢!
最佳答案
正如我在评论中所说,您不能委托给正确的重载extractStuff
,因为要调用的重载方法必须在编译时确定。
我建议在这里提供一个选项,通过将所有if.. else
替换为预定义的映射来减少所有obj
的代码混乱。
假设extractStuff
具有基本类型,则可以为obj
类型的每个子类定义要调用的重载Number
。
Map<Class<? extends Number>, Function<Number, String>> mappings = new HashMap<>();
mappings.put(Integer.class, i -> extractStuff((Integer) i));
mappings.put(Float.class, f -> extractStuff((Float) f));
mappings.put(Long.class, l -> extractStuff((Long) l));
在这里,
extractStuff
是基本类型,对于Number
的某些子类型,我们具有extractStuff
。private static String extractStuff(Integer obj) {
System.out.println(obj);
return "Integer called";
}
private static String extractStuff(Float obj) {
System.out.println(obj);
return "Float called";
}
private static String extractStuff(Long obj) {
System.out.println(obj);
return "Long called";
}
现在,我们可以通过传递得到的运行时对象的类来查找
mappings
,从而将其委托给正确的test(new BigDecimal(1));
public static void test(Number n) {
System.out.println(mappings.get(n.getClass()).apply(n));
}
呼叫码
test(1);
test(1f);
test(1L);
此打印
1
Integer called
1.0
Float called
1
Long called
您需要处理丢失的映射。
示例:
编辑:
感谢Bubletan @提出的建议
当您遇到缺少的映射时,可以循环遍历继承层次结构,直到找到一个映射为止
for (Class<?> c = n.getClass(); c != Object.class; c = c.getSuperclass()) {
//process and break once you found an entry in the map
}