2013-04-23 30 views
2

爲什麼我必須在下面的代碼中顯式地將命令轉換爲C? 命令實現Runnable和Describable。如何在使用兩個接口聲明泛型類型參數時避免不必要的強制轉換

@Test 
public <C extends Runnable & Describable> void testMapOfCommands() throws Exception 
{ 
    Map<String, C> commands = Maps.newHashMap(); 
    for(Commands command : Commands.values()) 
    { 
     commands.put(command.name(), (C) command); 
    } 
    //Use commands here (not relevant to my question): 
    //CommandLineParser.withCommands(commands).parse("commit"); 
} 

private enum Commands implements Runnable, Describable 
{ 
    commit 
    { 
     @Override 
     public void run() 
     { 
      System.out.println("COMMIT"); 
     } 

     @Override 
     public String description() 
     { 
      return "Commits something"; 
     } 
    }; 
} 

一個解決辦法我心目中是介紹的ICommand擴展雙方的Runnable和可描述的:

public interface ICommand extends Runnable, Describable{} 

,但我想避免引入一個新的類型時,已經有兩種類型隨時可用,我已經有了一個更復雜一點的Command類。我在這裏抓秸稈嗎?

+0

他們是接口 – jontejj 2013-04-23 22:03:56

+0

首先,請發佈整個班級。其次,你需要使用實現,而不是擴展,像Runnable這樣的接口。 – Antimony 2013-04-23 22:04:39

+0

更新了一下代碼,我認爲所有相關代碼都已發佈。你錯過了哪些部分? – jontejj 2013-04-23 22:07:09

回答

6

什麼是command對象是Commands類型。但是由於您的泛型類型聲明<C extends Runnable & Describable>,Java期望C既是Describable也是Runnable,但C不是必需的Commands

這個特殊的測試方法並不是用於除Commands以外的任何其他工作,所以它不應該是通用的。這應該工作:

public void testMapOfCommands() throws Exception 
{ 
    Map<String, Commands> commands = new HashMap<String, Commands>(); 
    for(Commands command : Commands.values()) 
    { 
     commands.put(command.name(), command); 
    } 
} 
+0

+1。正是我的評論:-) – 2013-04-23 22:12:15

+0

這工作!謝謝。不過,如果我能理解爲什麼編譯器不能將命令轉換爲Runnable&Describable,我將不勝感激。我的代碼工作得很好,只是(C)命令強制轉換有點奇怪。 – jontejj 2013-04-23 22:17:18

+0

Java編譯器認爲C可以是_anything_,它既實現'Runnable'又實現'Describable',即使它是一個'Commands2',恰好也是'Describable'和'Runnable'。所以它不允許'Commands'類型的參數,因爲你不應該把'Commands'放到可能是'HashMap '的東西里(即使我們知道它真的不是)。 – rgettman 2013-04-23 22:20:28

相關問題