Дерево иерархии уже неявно определяется объявлением классов. Вам просто нужно пересечь одну ветвь дерева через цепочку getSuperclass()
вызовов типа, который вы хотите найти. Затем узлы дерева (типы классов) могут быть организованы с использованием простой хэш-карты.
Учитывая, что иерархия типов является статическим, вы можете определить его как перечисление
public enum ClassType{
HOMINOIDEA(HOMINOIDEA.class),
HOMINIDAE(HOMINIDAE.class),
HOMININAE(HOMININAE.class),
//and so on
UNKNOWN(null);
private static final Map<Class<?>, ClassType> typesMap = new HashMap<>();
public final Class<?> type;
static{
for (ClassType classType : EnumSet.allOf(ClassType.class)){
if(classType.type != null){
typesMap.put(classType.type, classType);
}
}
}
private ClassType(Class<?> type){
this.type = type;
}
public static ClassType getClassTypeOf(Class<?> type){
for(Class<?> lookupType = type; lookupType != null; lookupType = lookupType.getSuperclass()){
ClassType classType = typesMap.get(lookupType);
if(classType != null){
return classType;
}
}
return UNKNOWN;
}
}
, а затем сопоставить типы классов к действиям:
public static void main(String[] args){
EnumMap<ClassType, Action> actionMap = new EnumMap<>(ClassType.class);
actionMap.put(ClassType.HOMININAE, new HomininaeAction());
Homininae h = new Homininae();
actionMap.get(ClassType.getClassTypeOf(h)); //action associated with homininaes
}
Вот другие в некоторых терминах более динамическая версия
public class ActionDispatcher {
private final Map<Class<?>, Consumer<?>> actionMap = new HashMap<>();
public <T> void registerAction(Class<T> type, Consumer<? super T> action){
actionMap.put(type, action);
}
@SuppressWarnings("unchecked")
public void dispatchActionFor(Object object){
Consumer<Object> action = ((Consumer<Object>)getActionFor(object.getClass()));
if(action != null){
action.accept(object);
}
}
private Consumer<?> getActionFor(Class<?> type){
for(Class<?> lookupType = type; lookupType != null; lookupType = lookupType.getSuperclass()){
Consumer<?> action = actionMap.get(lookupType);
if(action != null){
return action;
}
}
return null;
}
//demo
public static void main(String[] args){
ActionDispatcher dispatcher = new ActionDispatcher();
dispatcher.registerAction(Number.class, n -> System.out.println("number: " + n));
dispatcher.registerAction(Double.class, d -> System.out.println("double: " + d));
dispatcher.registerAction(String.class, s -> System.out.println("first char: " + s.charAt(0)));
dispatcher.registerAction(Object.class, o -> System.out.println("object: " + o));
dispatcher.dispatchActionFor(new Integer(3));
dispatcher.dispatchActionFor(new Double(3.0));
dispatcher.dispatchActionFor("string");
dispatcher.dispatchActionFor(new Thread());
}
}
Выход этого:
number: 3
double: 3.0
first char: s
object: Thread[Thread-0,5,main]
Решение, которое я имею в виду обходе дерева кортежей типа и связанных с ними действий. – mike
Вы хотите проверить тип данного объекта? Можете ли вы привести пример кода? –
Не уверен, что я понимаю. Если у вас есть объекты, принадлежащие к вышеуказанной иерархии классов/типов, и методы, представляющие действия, то вызов этих методов на объектах будет автоматически вызывать наиболее конкретное действие. – user152468