【发布时间】: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<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> 的值可以被不同的状态更改,然后在原始状态需要时检索。一种共享内存模型。
这个概念多年来一直运行良好(是的,这是遗留问题),但我们最近开始迁移到 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