Java 8 - 将Integer转换为长编译问题

时间:2014-11-24 12:50:39

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

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

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 + "]";
    }
}

InputCollection包含Objects列表:

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<E>,就像这样:

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<E>的实例又由许多州共享&#39;或者&#39;进程&#39;。然后可以通过不同的状态更改main的值,然后在原始状态需要时检索它。一种共享内存模型。

这个概念多年来一直运行良好(是的,这是遗留的),但我们最近开始转向Java 8,这就产生了编译错误,即使实现在Java 7上有效。

将以下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); } } 添加到上面的代码示例中:

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

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

Type mismatch: cannot convert from Integer to long

但如果在行

上设置为1.8编译错误long longValue = collection.getValue(Input.INTEGER_ONE, -1);
long longVal = Input.INTEGER_ONE.getValue();

但是,如果我访问这个值:

{{1}}

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

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

Java 8中需要演员的变化是什么?编译是否变得更加严格?如果值是直接访问而不是通过集合,编译器为什么不抱怨?

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

2 个答案:

答案 0 :(得分:8)

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

  

<强> 5.1.2。扩大原始转换

     

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

     

[..]

     
      
  • int to long,float或double
  •   
     

[..]

     

<强> 5.1.8。取消装箱转换

     

[..]

     
      
  • 从类型Integer到类型int
  •   

应该从Integerint进行拆箱,然后扩展转换为long。这实际上正如Oracle JDK(1.8.0.25)中所期望的那样发生。

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

答案 1 :(得分:6)

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

已在Eclipse 4.5 M3中修复。