我需要对不确定类型的对象进行操作,我知道它可以采用哪种类型,但是我无法控制这些类型。我无法修改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
}

09-11 18:12