Java 不控制引用类的调度模式的任何方法

Java 不控制引用类的调度模式的任何方法,java,Java,我需要对不确定类型的对象进行操作,我知道它可以假设哪些类型,但我无法控制这些类型。我不能修改类A,B 是否有比以下更好的解决方案: if (obj instanceof A) return extractA((A) obj); if (obj instanceof B) return extractB((B) obj); .... 谢谢 正如我在评论中所说,您不能将重载的extractsuff委托给右侧,因为要调用的重载方法必须在编译时决定 我建议在这里使用所有

我需要对不确定类型的对象进行操作,我知道它可以假设哪些类型,但我无法控制这些类型。我不能修改类A,B

是否有比以下更好的解决方案:

if (obj instanceof A)
        return extractA((A) obj);
if (obj instanceof B)
        return extractB((B) obj);
....

谢谢

正如我在评论中所说,您不能将重载的
extractsuff
委托给右侧,因为要调用的重载方法必须在编译时决定

我建议在这里使用所有
if。。否则
,将其替换为预定义的映射

假设
obj
有一个基类型,您可以为
obj
类型的每个子类定义要调用的重载
extractsuff

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

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
您需要处理丢失的映射。
示例:
test(新的BigDecimal(1))

编辑: 感谢Bubletan@的建议

当遇到缺少的映射时,可以通过遍历继承层次结构循环直到找到一个映射

for (Class<?> c = n.getClass(); c != Object.class; c = c.getSuperclass()) { 
   //process and break once you found an entry in the map
}
for(Class c=n.getClass();c!=Object.Class;c=c.getSuperclass()){
//在地图中找到条目后处理并中断
}

如果您已经重载了方法
提取(A)
提取(B)
,则不必使用
实例和强制转换来检测类型。Java中的方法分派就可以做到这一点

只需创建一个实用程序类(此处为
TypeFacade
),其中包含所有受支持类型的重载方法,例如

public class ClassCaster {

  public static class A {
    public String getName() {
        return "A";
    }
  }

  public static class B {
    public String getMyName() {
        return "b";
    }
  }

  public static class C {
    public String getClassName() {
        return "C";
    }
  }

  public static class TypeFacade {

    public static String extractName(A a) {
        return a.getName();
    }

    public static String extractName(B b) {
        return b.getMyName();
    }

    public static String extractName(C c) {
        return c.getClassName();
    }
  }

  public static void main(String[] args) {
    System.out.println(TypeFacade.extractName(new A()));
    System.out.println(TypeFacade.extractName(new B()));
    System.out.println(TypeFacade.extractName(new C()));
  }
}

那么每种类型都有不同的
extractStuff
方法吗?没有。那么你的意图是什么?你期望
extractsuff
如何工作(或者换句话说,你期望通过什么?@user7 bruh我不知道。然后,您不能在运行时基于类型将其委托给右侧的
extractStuff
,因为这(选择重载方法)必须在编译时发生,您所说的基类型是什么意思?这些对象实现了可序列化,但我不能使用该类型,除此之外,我不扩展除对象之外的任何内容。编辑:我想我现在清楚基本类型了。我指的是在
extractsuff
中处理的所有类型的公共类型(某种程度上是最不常见的祖先)。最坏的情况是Object。如果你的类可能有子类,你必须对(类c=n.getClass();c!=Object.Class;c=c.getSuperclass()){…}
执行一个循环
,并调用
mappings.get(c)
,直到你找到一些东西为止。@Bubletan这可能是一种方法。我已经提到,这是必须处理的。我已经用你的输入更新了答案。
public class ClassCaster {

  public static class A {
    public String getName() {
        return "A";
    }
  }

  public static class B {
    public String getMyName() {
        return "b";
    }
  }

  public static class C {
    public String getClassName() {
        return "C";
    }
  }

  public static class TypeFacade {

    public static String extractName(A a) {
        return a.getName();
    }

    public static String extractName(B b) {
        return b.getMyName();
    }

    public static String extractName(C c) {
        return c.getClassName();
    }
  }

  public static void main(String[] args) {
    System.out.println(TypeFacade.extractName(new A()));
    System.out.println(TypeFacade.extractName(new B()));
    System.out.println(TypeFacade.extractName(new C()));
  }
}