有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java整数。如果未首先将longValue()指定给数字,则会引发异常

public Long getId()
{
    Some code ...

    TypedQuery<Long> query = entityManager.createQuery(sQuery, Long.class);
    return query.getSingleResult();
}

从这段代码中,我得到一个从IntegerLongClassCastException。我在调试器中选中了query.getSingleResult();,并将Integer5保存下来

如果我将代码更改为query.getSingleResult().longValue();,它仍然无法工作。我也有同样的例外。但是如果我使用

Number tmp = query.getSingleResult();
return tmp.longValue();

它起作用了。我的问题是为什么第一个解决方案不起作用Surley我可以更改我的查询,但我只想知道为什么secound可以工作而第一个不能

请随意更改我问题的标题。提前谢谢


共 (3) 个答案

  1. # 1 楼答案

    第一种方法不起作用,因为你用了错误的方法来制作这个角色。这个类的树是这样的:

    enter image description here

    正确的方法是先将整数转换为数字,然后转换为Long调用longValue()方法

    第二种方法之所以有效,是因为您遵循了正确的步骤来转换这两种类型的数字

    看看下面的印刷品。编译器不喜欢这种类型转换的方式。不仅仅是很长时间,对于BigDecimal和其他数字也是如此

    enter image description here

  2. # 2 楼答案

    您的查询实际上返回一个Integer,但您通过调用entityManager.createQuery(sQuery, Long.class)假装它返回一个Long

    现在当你执行

    query.getSingleResult()
    query.getSingleResult().longValue()
    

    由于您的泛型声明,编译器会将强制转换插入Long。因此,这实际上是执行的:

    (Long)query.getSingleResult()
    ((Long)query.getSingleResult()).longValue()
    

    抛出ClassCastException,因为Integer不是Long

    当你打电话的时候

    Number tmp = query.getSingleResult();
    

    它实际上表现得很好

    Number tmp = (Number)query.getSingleResult();
    

    这段代码成功了,因为IntegerNumber

    所以不是longValue()抛出异常,而是之前发生的强制转换

  3. # 3 楼答案

    {}的规范说明:

    The select list of the query must contain only a single item, which must be assignable to the type specified by the resultClass argument.

    因此,您会遇到问题,因为Integer不可分配给Long。然而,有趣的是,为什么一个版本抛出一个异常,而另一个版本不抛出异常。p>

    我将使用更熟悉的类来解释使用类型为Number的临时变量和不使用类型的临时变量之间的区别

    这个例子抛出一个ClassCastException

     List<Long> list = (List<Long>) (List) Collections.singletonList(5); // Very dodgy.
     list.get(0).longValue();
    

    原因是泛型只是一种编译时功能,如果需要,可以在其中插入不可见的强制转换。实际上,list.get(0)只是一个Object,而且Object没有方法longValue。cast的类型不是该方法中最不具体的类型,而是简单的Long。因此,第二行变为

    ((Long) list.get(0)).longValue();
    

    然后抛出一个ClassCastException

    另一方面,如果你这样做了

    Number a = list.get(0);
    a.longValue();
    

    不需要不可见的强制转换来键入Long,因为Number已经有了一个方法longValue。此版本不会引发异常