Java编译器拒绝使用参数化内部类的变量声明

时间:2012-08-28 21:49:53

标签: java generics groovy inner-classes

我有一些Groovy代码可以在Groovy字节码编译器中正常工作,但是它生成的Java存根会导致Java编译器出错。我认为这可能是Groovy存根生成器中的另一个错误,但我真的无法弄清楚为什么Java编译器不喜欢生成的代码。

这是生成的Java类的截断版本(请原谅丑陋的格式化):

@groovy.util.logging.Log4j() public abstract class AbstractProcessingQueue
<T>  extends nz.ac.auckland.digitizer.AbstractAgent  implements
    groovy.lang.GroovyObject {
        protected int retryFrequency;
        protected java.util.Queue<nz.ac.auckland.digitizer.AbstractProcessingQueue.ProcessingQueueMember<T>> items;
        public AbstractProcessingQueue
        (int processFrequency, int timeout, int retryFrequency) {
             super ((int)0, (int)0);
    }

    private enum ProcessState
      implements
    groovy.lang.GroovyObject {
        NEW, FAILED, FINISHED;
    }

    private class ProcessingQueueMember<E>  extends java.lang.Object  implements
    groovy.lang.GroovyObject {
        public ProcessingQueueMember
        (E object) {}
    }
}

生成的代码中的违规行是:

protected java.util.Queue<nz.ac.auckland.digitizer.AbstractProcessingQueue.ProcessingQueueMember<T>> items;

产生以下编译错误:

[ERROR] C:\Documents and Settings\Administrator\digitizer\target\generated-sources\groovy-stubs\main\nz\ac\auckland\digitizer\AbstractProcessingQueue.java:[14,96] error: improperly formed type, type arguments given on a raw type

编译错误中的列索引96指向<T>类型的ProcessingQueueMember参数化。但是ProcessingQueueMember不是编译器声称的原始类型,它是泛型类型:

private class ProcessingQueueMember
<E>  extends java.lang.Object  implements
groovy.lang.GroovyObject { ...

我很困惑为什么编译器认为类型Queue<ProcessingQueueMember<T>>无效。 Groovy源编译得很好,生成的Java代码看起来也非常正确。我在这里错过了什么?是否与所讨论的类型是嵌套类这一事实有关?

(如果有人有兴趣,我已在此问题中提交了与this bug report相关的问题)

编辑:原来这确实是一个存根编译器错误 - 这个问题现在已经在1.8.9,2.0.4和2.1中得到修复,所以如果你仍然遇到这个问题,只需升级到其中一个版本。 :)

2 个答案:

答案 0 :(得分:8)

由于ProcessingQueueMember类是AbstractProcessingQueue的非静态内部类,因此其正文可以引用T的{​​{1}}类型参数。因此,对AbstractProcessingQueue的非原始引用必须提供两个类型参数。例如,

ProcessingQueueMember

将编译。此代码可能过于通用。我相信你真的想要这两种选择中的一种:

  1. 使protected java.util.Queue<AbstractProcessingQueue<T>.ProcessingQueueMember<T>> items; 静态(即嵌套类而不是内部类)
  2. ProcessingQueueMember<E>
  3. 中删除类型参数

    我对groovy存根生成器一无所知,但也许有一些方法可以注释你的groovy代码来表达它?

答案 1 :(得分:0)

可能缺少包含变量声明(protected java.util.Queue<nz.ac.auckland.digitizer.AbstractProcessingQueue.ProcessingQueueMember<T>> items;)的类的泛型类型参数?