2013-01-20 31 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