【问题标题】:Java generics code compilation issues when building outside of Eclipse在 Eclipse 之外构建时的 Java 泛型代码编译问题
【发布时间】:2011-01-22 22:01:07
【问题描述】:

我已经为我拥有的一个非常小的 GWT 项目配置了一个 Maven 构建。从 Eclipse 编译/运行没有问题,但是当我执行 Maven 构建时,我在一个地方遇到了编译问题(这是 GWT 的“客户端”代码,但我不确定是否是这种情况)。 Maven/编译输出:

[..]SmartTable.java:[63,52] ')' expected
[..]SmartTable.java:[63,53] ')' expected
[..]SmartTable.java:[63,69] ';' expected
[..]SmartTable.java:[63,71] not a statement
[..]SmartTable.java:[63,77] ';' expected
[..]SmartTable.java:[63,79] not a statement

.. 此处特定行定义如下:

final Comparator<T> comparator = ((SmartTable<T>.ComparableColumn) column).comparator;

正如您所猜到的,我正在遍历为此泛型类定义的所有列(我称之为“SmartTable”),并获取一个比较器(当然,如果列 instanceof SmartTable.ComparableColumn)以进行进一步操作。 'Column' 和 'ComparableColumn' 类嵌套在 SmartTable 中,它们的标题如下所示:

public abstract class Column {
    // private String id;
    private String caption;
    private int width;
    private Filter<T> filter;
...
public class ComparableColumn extends Column {
    private Comparator<T> comparator;
...

当它从 Eclipse 编译时,我在打包 WAR(没有“干净” - 简单的包,因为 Eclipse 配置为将 .class 文件放置在 Maven 使用的同一目标目录中)和部署/运行它时没有问题正确。

我已经尝试过更改 maven-compiler-plugin 和配置(设置值 1.5、1.6 和 1.4 - 为了实验,看看它是否会开始抱怨泛型),但这没有帮助. Eclipse 项目编译器合规性是默认的 (1.6)。看来我对其他泛型代码没有其他编译问题。

试图让它尽可能短,但不确定我是否做得好:)

编辑:按需求提供更多代码

public class SmartTable<T> extends FlexTable {
    private List<Column> columns = new ArrayList<Column>();
    ...
    private Comparator<T> currentComparator;
...

    public void init(Comparator<T> defaultComparator) {
        this.currentComparator = defaultComparator;
        ...
        int index = 0;
        for (Column column : columns) {
            ...
            if (column instanceof SmartTable.ComparableColumn) {
                @SuppressWarnings("unchecked")
                final Comparator<T> comparator = ((SmartTable<T>.ComparableColumn) column).comparator;
            ...
    }
...

    public abstract class Column {
        // private String id;
        private String caption;
        private int width;
        private Filter<T> filter;
        private List<WidgetCreator<T>> widgetCreators;

        public Column(/* String id, */String caption, int width, Filter<T> filter, List<WidgetCreator<T>> widgetCreators) {

...

    public class SimpleColumn extends Column {
        public SimpleColumn(/* String id, */String caption, int width, Filter<T> filter, List<WidgetCreator<T>> widgetCreators) {
            super(/* id, */caption, width, filter, widgetCreators);
        }

...

    public class ComparableColumn extends Column {
        private Comparator<T> comparator;

        public ComparableColumn(/* String id, */String caption, int width, Filter<T> filter,
                List<WidgetCreator<T>> widgetCreators, Comparator<T> comparator) {
            super(/* id, */caption, width, filter, widgetCreators);
            this.comparator = comparator;
        }

...

}

EDIT2:实际问题似乎非常集中:)

public class SmartTable2<T> {
    public void init() {
        Column c = new ComparableColumn();

        final Comparator<T> comparator = ((SmartTable2<T>.ComparableColumn) c).comparator;
    }

    class Column {

    }

    class ComparableColumn extends Column {
        Comparator<T> comparator;
    }
}

EDIT3:一些想法,希望更接近解决方案 ..所以这不能简单地用javac编译,抛出完全相同的编译错误。所以我刚刚学到的是:Eclipse 使用它自己的内部 Java 编译器——它是 JDT Core 的一部分(希望我没有误解它);那么JDT编译器是否能够编译这样的语法,而Sun的JDK javac不能? (哎呀,Oracle 不是 Sun)

【问题讨论】:

标签: java eclipse gwt


【解决方案1】:

试试这个语法:

Comparator<T> comparator = (Comparator<T>) ((SmartTable.ComparableColumn) column).comparator;

编辑: 演员阵容没用:

Comparator<T> comparator = ((SmartTable.ComparableColumn) column).comparator;

这和你的场景相似吗?

public class Main {

    public static <T> void main(String[] args) throws Exception {
        SmartTable<T>.Column column = new SmartTable<T>().new Column();
        Comparator<T> comparator = ((SmartTable.ComparableColumn) column).comparator;

    }

    static class SmartTable<T> {
        class Column {

        }
        class ComparableColumn extends Column {
            Comparator<T> comparator;
        }
    }

}

这可以用 javac 很好地编译(当然,带有未经检查的警告),而尝试将转换编译为 (SmartTable.ComparableColumn) 会导致您的帖子中出现错误。

编辑(所有编辑): 您的问题似乎以前被问过:Casting to an inner class with generics,答案似乎是编译器错误:http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6665356

【讨论】:

  • 这将导致其他编译错误(我想这些是 GWT 编译后错误): [INFO] 验证新编译的单元 [INFO] [ERROR] 'file:/D: 中的错误: /[..]/SmartTable.java' [INFO] [ERROR] 第 63 行:无法从 SmartTable.Column 转换为 SmartTable.ComparableColumn
  • 嗯...删除上面 SmartTable.Column 声明中的 ... 但是,在我的机器上使用相同的类声明它编译得很好。这个演员表问题应该只是一个未经检查的警告......
  • 代码(如您在编辑后建议的那样): final Comparator 比较器 = ((SmartTable.ComparableColumn) column).comparator;输出:[INFO] [ERROR] 第 63 行:无法从 SmartTable.Column 转换为 SmartTable.ComparableColumn
  • 我知道 SmartTable 是唯一的通用类:SmartTable... 我可以看到所有三个类声明吗? (我想这两个 Column 类都是 SmartTable 的非静态内部类)。以及该行上方列变量的声明?
  • 编辑前和编辑后的代码版本是相同的——强制转换是无用的,因为无论如何都会引发未经检查的警告。
【解决方案2】:

按以下方式使用它。我的意思是直接将以下插件添加到 pom.xml 文件中。

org.apache.maven.plugins maven 编译器插件 1.5 1.5

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-12
    • 1970-01-01
    • 2012-04-09
    • 1970-01-01
    • 2017-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多