inheritance感知类到值映射以替换`instanceof`系列

我正在寻找一些神奇的类似Map的实用程序,给定一个类型,返回与该类型或其最接近的超类型相关联的值。 这是替换语句之类的

 if (... instanceof A) return valueA; else if (... instanceof B) return valueB; ... 

我已经阅读了Java中避免使用instanceof的答案,它提出了许多模式,特别是访问者模式。 但是,由于目标是返回一个简单的值,实现访问者似乎是一种矫枉过正。

不幸的是,新的JDK类ClassValue也没有资格,因为它不检查超类型。

我只是想在我自己推出之前检查这个实用程序是否存在于任何知名库中。 实现应该是线程安全的,并且希望插入的值的数量小于线性成本。

地图会做。 如果你想要类inheritance,你需要向上走。

 private final Map, Object> map = HashMap<>(); public void register(Class clazz, Object value) { map.put(clazz, value); } public Object getValue(Class clazz) { if (clazz == null) { return null; } Object value = map.get(clazz); if (value == null) { clazz = clazz.getSuperclass(); // May be null. return getValue(clazz); } } 

这对于int.classint.class

如果价值和阶级之间存在关系:

 public  T getValue(Class clazz) { Object value = map.get(clazz); return clazz.cast(value); } 

您可以使用具有default方法的interface删除大部分残差来进行地图查找。 您仍然必须以某种方式注册每个类 – 我使用了static初始化程序,您可能有一个更好的方法。

 interface HasClassValue { // My big map. static final Map, Long> values = new HashMap<>(); default Optional value() { Class c = this.getClass(); do { // Climb the class tree. Long value = values.get(c); if (value != null) { // Found it. return Optional.of(value); } // Up! c = c.getSuperclass(); } while (c != null); // Not found. return Optional.empty(); } // Maintain the map. public static void register(Class c, long value) { values.put(c, value); } } static class X implements HasClassValue { static { HasClassValue.register(X.class, 100); } } static class Y extends X { static { HasClassValue.register(Y.class, 200); } } static class Z extends Y { } public void test() { X x = new X(); Y y = new Y(); Z z = new Z(); System.out.println("X - " + x.value()); System.out.println("Y - " + y.value()); System.out.println("Z - " + z.value()); } 

我用以下解决方案解决了我的项目中的问题。

 GenericClass object = (GenericClass) Class.forName(specificClassName).newInstance(); 

我定义了一个GenericClassBase class )。 我有许多这些generics类的具体实现。 Specific concrete class将加载className我作为参数传递。