Switch over type in java

后端 未结 8 1137
执念已碎
执念已碎 2020-12-02 14:23

Before I start, I know there are a bunch of answers to this question that suggest alternate approaches. I\'m looking for assistance to this particular approach as to whethe

8条回答
  •  天命终不由人
    2020-12-02 15:12

    You was very close to the solution with enums. It hasn't compiled because your enum missed constructor and coversion method to map enum from String. Actually you could solve it even without String, i.e. without calling getCanonicalName at all:

    public enum Classes {
      // changed enum constants a bit to avoid confusing with target class names
      ClsA (A.class),
      ClsB (B.class),
      ClsC (C.class),
      UNKNOWN(null);
      private final Class targetClass;
      Classes(Class targetClass) {
        this.targetClass = targetClass;
      }
      public static Classes fromClass(Class cls) {
        for(Classes c : values()) {
          if(c.targetClass == cls)
             return c;
        }
        return UNKNOWN;
      }
    }
    
    switch (Classes.fromClass(o.getClass())) {
    case ClsA:
      handleA((A)o);
      break;
    case ClsB:
      handleB((B)o);
      break;
    case ClsC:
      handleC((C)o);
      break;
    default:
      handleUnknown(o);
      break;
    }
    

    if you get significant count of known classes, consider using map instead of iterating in Classes.fromClass, e.g.:

    public enum Classes {
      ClsA(A.class),
      ClsB(B.class),
      // etc...
      UNKNWON(null);
    
      // need a wrapper class to avoid compilation problem
      // with referring static enum field within an initializer 
      private static class Holder {
        public static final IdentityHashMap, Classes> map = new IdentityHashMap<>();
      }
      Classes(Class targetClass) {
        Holder.map.put(targetClass, this);
      }
      public static Classes fromClass(Class cls) {
        Classes c = Holder.map.get(cls);
        return c != null ? c : UNKNOWN;
      }
    }
    

提交回复
热议问题