2011-11-08 68 views
0

的枚舉的枚舉方法我有以下接口返回特定接口

public interface DeviceKey { 
    String getKey(); 
} 

我也有所有擴展了此界面的各種枚舉。

在包含所有枚舉的類中,我想要一個基於字符串(key)的方法,可以返回對應於此字符串的枚舉。該字符串與枚舉相關,但不是名稱。我的階級和枚舉看起來是這樣的:

public class Settings { 
    private static final Map<String, DeviceKey> lookupAll = Maps.newHashMap(); 
    static { 
     lookupAll.putAll(SmartSetting.lookup); 
     // Plus a lot more similar to these 
    } 

    public static DeviceKey valueOfAnyKey(String key) { 
     return lookupAll.get(key); 
    } 

    public enum SmartSetting implements DeviceKey { 
     STATUS("smart_status"); 

     private static final Map<String, SmartSetting> lookup = EnumUtil.addAll(SmartSetting.class); 
     private final String key; 

     SmartEncryptionSetting(String key) { 
      this.key = key; 
     } 

     @Override 
     public String getKey() { 
      return key; 
     } 
    } 
} 

目前執行的valueOfAnyKey()回報DeviceKey這當然不是一個枚舉。我應該怎麼做才能使valueOfAnyKey()返回一個類型爲DeviceKey的枚舉?

的EnumUtil:

private static class EnumUtil { 

    public static <T extends Enum<T> & DeviceKey> Map<String, T> addAll(Class<T> theClass) { 
     final Map<String, T> retval = new HashMap<String, T>(); 
     for(T s : EnumSet.allOf(theClass)) { 
      retval.put(s.getKey(), s); 
     } 
     return retval; 
    } 
} 

回答

0

在Java的方法只能返回一個類型。你不能讓它返回DeviceKey「和」Enum

+0

儘管最終的代碼是在我的答案中寫的,但我選擇這是正確的答案。我這樣做是因爲看着原來的問題,這是正確的答案。一開始就不可能獲得我一直在尋找的東西。 – homaxto

0

也許是這樣的:

import java.util.*; 
interface Key { 
    String get(); 
} 
class Enums { 
    enum Color implements Key { 
     r("foo"), g("bar"), b("baz"); 
     Color(String key) { 
      this.key = key; 
     } 
     public String get() { 
      return key; 
     } 
     final String key; 
    } 
    enum Day implements Key { 
     m("quux"), t("fred"), w("hozer"); 
     Day(String key) { 
      this.key = key; 
     } 
     public String get() { 
      return key; 
     } 
     final String key; 
    } 
    static final Map<String, Enum> map = new LinkedHashMap<String, Enum>(); 
    static { 
     for (Color c : Color.values()) 
      map.put(c.get(), c); 
     for (Day d : Day.values()) 
      map.put(d.get(), d); 
    } 
} 
public class Main { 
    public static void main(String[] args) { 
     for (Enums.Color c : Enums.Color.values()) 
      System.out.println(c+" "+c.get()+" "+Enums.map.get(c.get())); 
     for (Enums.Day d : Enums.Day.values()) 
      System.out.println(d+" "+d.get()+" "+Enums.map.get(d.get())); 
    } 
} 
+0

這將返回一個枚舉,但它不會訪問從DeviceKey接口實現的方法。 – homaxto

+0

static final地圖 map = new LinkedHashMap (); //這樣做,而不是 –

+0

然後它是一個密鑰,它不能用於例如。在switch語句中。我需要的是返回一個特定類型的枚舉(我的界面)。我開始認爲這是不可能的,即使是仿製藥。 – homaxto

0

那麼,經過這段時間後,一個同事找到了一種解決方案。對枚舉的更改很少,並且在調用valueOfAnyKey()時也需要進行一些更改。 所以現在我們可以得到一個我們知道是Enum的DeviceKey。

public class Settings { 
    private static final Map<String, Enum<?>> lookupAll = Maps.newHashMap(); 
    static { 
     lookupAll.putAll(SmartSetting.lookup); 
     // Plus a lot more similar to these 
    } 

    public static <T extends Enum<T> & DeviceKey> T valueOfAnyKey(String name) { 
     return (T) lookupAll.get(name); 
    } 

    public enum SmartSetting implements DeviceKey { 
     STATUS("smart_status"); 

     private static final Map<String, SmartSetting> lookup = EnumUtil.addAll(SmartSetting.class); 
     private final String key; 

     SmartEncryptionSetting(String key) { 
      this.key = key; 
     } 

     @Override 
     public String getKey() { 
      return key; 
     } 
    } 
} 

查找設置現在按照以下方法完成。 IntelliJ和eclipse都沒有遺漏<T>的任何問題,但Oracle編譯器堅持認爲它在那裏。

T setting = DeviceSetting.<T>valueOfAnyKey("settingName); 

<T>現在應該在方法或類級別上定義。如果它是在方法級別上定義的,那麼你有時也會遇到Oracle編譯器的問題,所以建議將定義添加到類中。

或者:

public class SomeClass <T extends Enum<T> & DeviceKey> { 
    .... 
} 

public class SomeClass { 
    public <T extends Enum<T> & DeviceKey> void aMethod() { 
     ... 
    } 
} 

這一切後,它仍然留給我們不知道什麼樣的枚舉,我們正在找回的,而且爲了使用setting(中類型T)我們需要使用SmartSetting.class.cast(setting)進行投射。 我們已經討論過,如果這實際上給了我們一個比Ray Tayek建議的更好的解決方案,這也是我們的第一個實現,並且結論是我們提供了一些關於返回內容的更多細節,但是從調用者角度看查看你將永遠需要做班級演員。