2013-01-20 56 views
0

我可以解決這個問題,但我無法理解它,所以我要求一些解釋(也許還有一個更好的問題標題)。枚舉編譯錯誤中的java匿名類

請考慮一下:

public class TBGService { 
    // TBGObject is an abstract base class which is extended by model classes 
    public <T> T doGet(TBGObject model) throws TBGServiceException { 
     String uri = model.buildUrl(repository) + model.getObjectKey(); 
     GetMethod method = new GetMethod(uri); 
     T returned = execute(method, credentials, model.getClass()); 
     return returned; 
    } 
} 

這:

public enum TBGTaskAttributes { 
    private TBGTaskAttributes(String id, String type, String label, Object... flags) { 
     builder = new TaskAttributeBuilder(); 
     builder.withId(id).withLabel(label); 
     for (Object flag : flags) { 
      processFlag(flag); 
     } 
    } 

    public abstract String getValueFromIssue(TBGIssue issue); 

    public abstract void setValueInIssue(TBGIssue issue, String value); 

} 

當我寫這篇文章的代碼來定義一個枚舉項:

PROJECT(TaskAttribute.PRODUCT, TaskAttribute.TYPE_SINGLE_SELECT, "Project", new OptionProvider() { 
    @Override 
    public Set<Entry<String, String>> getOptions(TaskRepository repository) { 
     try { 
      List<TBGProject> list = TBGService.get(repository) 
       .doGet(new TBGProjects()).getProjects(); 
      [...] 
      return map.entrySet(); 
     } catch (TBGServiceException e) { [...] } 
     return null; 
    } 
}) { 
    @Override 
    public String getValueFromIssue(TBGIssue issue) { 
     return issue.getProjectKey(); 
    } 
    @Override 
    public void setValueInIssue(TBGIssue issue, String value) { 
     issue.setProjectKey(value); 
    } 
}, 
[... other items ...] 

我得到編譯器錯誤(也蝕自動完成不起作用):

The method getProjects() is undefined for the type Object 

,如果我懸停doGet方法時,Eclipse其顯示爲像定義:

<Object> Object TBGService.doGet(TBGObject model) 

在其他地方,懸停示出正確的簽名:

<TBGProjects> TBGProjects TBGService.doGet(TBGObject model) 

當與參數new TBGProjects()調用。

只是改變:

List<TBGProject> list = TBGService.get(repository) 
    .doGet(new TBGProjects()).getProjects(); 

有:

TBGProjects projects = TBGService.get(repository).doGet(new TBGProjects()); 
List<TBGProject> = projects.getProjects(); 

使得它的工作。但是這裏發生了什麼?我錯過了什麼?

+0

BTW,傳遞一個類的實例一樣,是非常低效的。您應該接受'Class '參數並改爲傳遞'TBGProjects.class'。 – SLaks

+0

我明白了;但實際上,傳遞的類包含抽象超類所需的邏輯。入口點知道調用構造器的輸入,服務(作爲json客戶端)除抽象行爲外對此一無所知。將嘗試爲這個設計找到一個更好的模式。 –

+0

您可能想要在類上使用註釋而不是'getObjectKey()'。 – SLaks

回答

3

Java根據您指定方法返回值的原因推斷出T的類型。

如果您沒有將返回值分配給任何東西,Java不知道T應該是什麼。

爲了解決這個問題,你可以改變的參數是T類型,以便Java可以從你傳遞參數推斷T

public <T extends TBGObject> T doGet(T model) throws TBGServiceException { 
+0

哦,是的,這很容易,謝謝!並恭喜你的閱讀速度和對別人的理解速度代碼 –

+0

方面的問題:爲什麼同一個不變的電話從另一個班級上班? –

+0

@guido:我不知道爲什麼會這樣。你能告訴我一個完整的例子嗎? – SLaks