【问题标题】:java anonymous class in enum compilation error枚举编译错误中的java匿名类
【发布时间】:2013-01-20 23:56:58
【问题描述】:

我可以解决这个问题,但我无法理解,所以我要求一些解释(也许还有一个更好的问题标题)。

请考虑一下:

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 ...]

我得到编译器错误(eclipse自动完成也不起作用):

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();

让它工作。但是这里发生了什么?我错过了什么?

【问题讨论】:

  • 顺便说一句,像这样传递一个类实例是非常低效的。您应该接受 Class&lt;T&gt; 参数并改为传递 TBGProjects.class
  • 我明白了;但实际上传递的类包含抽象超类所需的逻辑。入口点知道调用构造函数的输入,服务(作为 json 客户端)除了抽象行为之外一无所知。将尝试为此设计找到更好的模式。
  • 您可能希望在类上使用注释而不是 getObjectKey()

标签: java generics enums anonymous-inner-class


【解决方案1】:

Java 根据您将方法的返回值分配给什么来推断 T 的类型。

如果你不给任何东西分配返回值,Java 不知道T 应该是什么。

要解决此问题,您可以将参数更改为 T 类型,以便 Java 可以从您传递的参数中推断出 T

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

【讨论】:

  • 哦,是的,就是这么简单,谢谢!并祝贺你快速阅读和理解别人的代码
  • 附带问题:为什么相同的未更改调用在另一个类中起作用?
  • @guido:我不知道为什么会这样。你能给我一个完整的编译示例吗?
  • 对不起我的错;另一个类正在调用同级方法,其中参数已经是通用的。再次感谢
  • 你怎么知道OP打算让参数和返回是相同的类型?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-04
相关资源
最近更新 更多