当前位置: 首页 > 面试题库 >

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

尤钱明
2023-03-14
问题内容

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

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>然后可以通过不同的状态更改an的值,然后在需要时由原始状态检索。一种共享内存模型。

这个概念已经运行了好多年(是的,这是遗留的),但是我们最近开始转向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中需要强制转换的变化是什么?编译变得更严格了吗?如果直接访问而不是通过集合访问值,为什么编译器不会抱怨呢?

我读了 在Java中如何从int转换为Long? 以及
将Integer转换为Long,但对我的问题并没有真正令人满意的答案。


问题答案:

根据Java
8
的JLS,这种情况不应发生:

5.1.2。 扩大原始转换

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

[..]

  • int转换为long,float或double

[..]

5.1.8。 拆箱转换

[..]

  • 从Integer类型到int类型

应该发生的是从Integer到的拆箱int,然后再扩展到long。这实际上是在Oracle JDK(1.8.0.25)中所预期的。

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



 类似资料:
  • 问题内容: 如何在Java中将值转换为值? 问题答案: 或如果您不必担心null: 在这两种情况下,您都可能会遇到溢出问题(因为Long可以比Integer存储更大的范围)。 Java 8有一个辅助方法来检查溢出(在这种情况下,您会得到一个异常):

  • 问题内容: 我正在尝试将字符串转换为,但是得到了。 我的字串是,现在我将其转换为我所拥有的任何一个。 我如何将其转换为它们中的任何一个。 请帮助我摆脱这个问题。 问题答案: 您必须为数字使用适当的语言环境,例如 版画

  • 问题内容: 任何方式投来? 引发异常 问题答案: A 不是,因此强制转换将不起作用。请注意Double 类和double 原始类型之间的区别。另请注意,a 是a ,因此它具有方法 ,你可以使用该方法将值作为原始值获取int。

  • 我是java.time包的新手。我有一个本地日期是2015-12-10。我需要将此转换为ZonedDateTime。时间应该是00:00:00,区域是zoneoffset.utc。 dateTimeException:无法从java.time.localDate类型的TemporalAccessor:2015-12-10获取Instant 我也试过: 这会产生意想不到的结果。 我查看了API并尝试

  • 本文向大家介绍在Java中将Double转换为Integer,包括了在Java中将Double转换为Integer的使用技巧和注意事项,需要的朋友参考一下 首先,初始化一个double值- 现在,使用intValue()方法将Double转换为Integer值- 示例 以下是在Java中将Double转换为Integer的程序- 输出结果

  • 问题内容: 我有以下整数形式的时间戳 我可以使用SQL进行转换: 如何在Java中转换它?这样它将返回值: 问题答案: 假设自1970年1月1日以来的时间(以秒为单位)。你可以试试