【问题标题】:Java 8 - converting an Integer to a long compilation issueJava 8 - 将整数转换为长编译问题
【发布时间】:2015-01-22 04:37:13
【问题描述】:

我的项目中有以下抽象通用数据持有者(简化版):

public abstract static class Value<E> {

    E value;

    public void setValue(E value) {
        this.value = value;
    }

    public E getValue() {
        return this.value;
    }

    public String toString() {
        return "[" + value + "]";
    }
}

连同一个包含Objects 列表的InputCollection

public static class InputCollection {

    private ArrayList<Object> values;

    public InputCollection() {
        this.values = new ArrayList<>();
    }

    public void addValue(Value<?> value) {
        System.out.println("addding " + value + " to collection");
        this.values.add(value);
    }

    public <D> D getValue(Value<D> value, D defaultValue) {
        int index = this.values.indexOf(value);
        if (index == -1) 
            return defaultValue;

        Object val = this.values.get(index);
        if (val == null) {
            return defaultValue;
        }

        return ((Value<D>)val).getValue();
    }
}

这背后的想法是能够定义一组final 变量,以所谓的“状态”实现此abstract Value&lt;E&gt;,如下所示:

public static final class Input<E> extends Value<E> {
    public static final Input<String> STRING_ONE = new Input<String>();
    public static final Input<Integer> INTEGER_ONE = new Input<Integer>();
}

然后,将这些变量添加到InputCollection 的实例中,该实例又被许多“状态”或“进程”共享。然后,Input&lt;E&gt; 的值可以被不同的状态更改,然后在原始状态需要时检索。一种共享内存模型。

这个概念多年来一直运行良好(是的,这是遗留问题),但我们最近开始迁移到 Java 8,这会产生编译错误,即使实现在 Java 7 上运行也是如此。

在上述代码示例中添加以下main

public static void main (String [] args) {

    InputCollection collection = new InputCollection();
    //Add input to collection
    collection.addValue(Input.STRING_ONE);
    collection.addValue(Input.INTEGER_ONE);

    //At some later stage the values are set
    Input.INTEGER_ONE.setValue(1);
    Input.STRING_ONE.setValue("one");

    //Original values are then accessed later
    long longValue = collection.getValue(Input.INTEGER_ONE, -1);

    if (longValue == -1) {
        System.out.println("Error: input not set");
    } else { 
        System.out.println("Input is: " + longValue);
    }
}

如果 eclipse 中的 Compiler Compliance 级别设置为 1.7,则不存在编译问题,输出正确为:

addding [null] to collection
addding [null] to collection
Input is: 1

但是如果设置为1.8编译错误Type mismatch: cannot convert from Integer to long就行了

long longValue = collection.getValue(Input.INTEGER_ONE, -1);

但如果我这样做访问值:

long longVal = Input.INTEGER_ONE.getValue();

没有编译问题,令人困惑。

它可以通过强制转换来解决,但这在整个项目中都使用过,并且需要进行相当多的强制性测试才能改变每次出现的情况。

Java 8 中有哪些需要强制转换的变化?编译是否以某种方式变得更严格了?如果值是直接访问而不是通过集合访问,为什么编译器不会抱怨?

我读过 How do I convert from int to Long in Java?Converting Integer to Long ,但我的问题并没有真正得到令人满意的答案。

【问题讨论】:

  • 你能试着用javac编译这个吗?我也有这个问题,我相信这是一个日食错误。如果我在代码中添加了演员表,它会发出“不必要的演员表”警告..​​.... :)
  • 我无法在我的机器上进行复制。它在我的 Java8 中运行良好。
  • 这实际上是 Eclipse 内部编译器中的一个错误。注意:Eclipse 不使用已安装 JDK 中的 javac 命令,而是使用内部编译器。此编译器报告错误。使用 JDK 工具编译它就可以了。
  • 我现在看到用javac 编译报告没有错误。那么一定是日食。
  • 似乎与stackoverflow.com/questions/25958687/… 中的问题相同(那里也没有答案,但有一个指向bugs.eclipse.org/bugs/show_bug.cgi?id=440019 的链接......可能也相关:stackoverflow.com/questions/5385743/…

标签: java eclipse generics java-8 long-integer


【解决方案1】:

一个已知的 Eclipse 错误:https://bugs.eclipse.org/bugs/show_bug.cgi?id=440019

在 Eclipse 4.5 M3 中已修复。

【讨论】:

  • 希望我有办法在 STS 3.6 中获得修复。有吗?
  • 我不知道。我只是下载了新版本,没问题。但是,是的,我可以想象一个您不想升级(或不能升级)的设置。尝试联系某个地方的 sts 人。
【解决方案2】:

根据JLS for Java 8,这不应该发生:

5.1.2。扩大基元转换

对原始类型的 19 种特定转换称为扩展原始类型转换:

[..]

  • int 到 long、float 或 double

[..]

5.1.8。拆箱转换

[..]

  • 从 Integer 类型到 int 类型

应该发生的是从Integerint 的拆箱,然后扩大到long 的转换。这实际上在 Oracle JDK (1.8.0.25) 中按预期发生。

我相信您在 JDK 中遇到了编译器错误。您可能应该尝试更新版本或向维护人员提交错误。

【讨论】:

  • 你是对的。使用 JDK 中的 javac 效果很好。这似乎是 Eclipse 编译器中的一个错误。
  • 这似乎已在 Eclipse Mars 4.5.0 中修复
猜你喜欢
  • 2011-10-05
  • 2011-05-30
  • 2011-05-20
  • 1970-01-01
  • 2017-04-13
  • 2021-04-09
  • 2016-02-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多