![](/img/trans.png)
[英]How to "map" two different object inheritance trees without instanceof
[英]Inheritance-aware class to value map to replace series of `instanceof`
我正在尋找一些神奇的類似Map
的實用程序,給定一個類型,返回與該類型或其最接近的超類型相關聯的值。 這是替換語句之類的
if (... instanceof A) return valueA;
else if (... instanceof B) return valueB;
...
我已經閱讀了Java中避免使用instanceof的答案,它提出了許多模式,特別是訪問者模式。 但是,由於目標是返回一個簡單的值,實現訪問者似乎是一種矯枉過正。
不幸的是,新的JDK類ClassValue
也沒有資格,因為它不檢查超類型。
我想在我自己推出之前檢查這個實用程序是否存在於任何知名庫中。 實現應該是線程安全的,並且希望具有低於線性成本和插入值的數量。
地圖會做。 如果你想要類繼承,你需要向上走。
private final Map<Class<?>, 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.class
等int.class
。
如果價值和階級之間存在關系:
public <T> T getValue(Class<T> clazz) {
Object value = map.get(clazz);
return clazz.cast(value);
}
您可以使用具有default
方法的interface
刪除大部分殘差來進行地圖查找。 你仍然需要以某種方式注冊每個類 - 我使用了static
初始化器,你可能有一個更好的方法。
interface HasClassValue {
// My big map.
static final Map<Class<?>, Long> values = new HashMap<>();
default Optional<Long> 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();
我定義了一個GenericClass
( Base class
)。 我有許多這些泛型類的具體實現。 Specific concrete class
將加載className我作為參數傳遞。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.