java.lang.ClassCastException: java.lang.Short无法转换为java.lang.Integer

3
在我的项目中,我有一个类似于这样的枚举类型:
public enum MyEnum {

FIRST(1),

SECOND(2);

private int value;

private MyEnum(int value) {
    this.value = value;
}

public int getValue() {
    return value;
}

public static MyEnum fromValue(int value) {
    for (MyEnum e : MyEnum.values()) {
        if (e.getValue() == value) {
            return e;
        }
    }
    return null;
}

我有这段代码:

Map<String, Object> myMap = new HashMap<>();
// Fill my Map with data from database
myMap = namedParameterJdbcTemplate.queryForList(qry, paramsMap);

***if (Arrays.asList(MyEnum.values())
                .contains(MyEnum.fromValue((int) 
                myMap.get("myKey")) )))*** {
    // Do something
    }

我收到了异常。
 java.lang.ClassCastException: java.lang.Short cannot be cast to java.lang.Integer** on this line : **if (Arrays.asList(MyEnum.values())
            .contains(MyEnum.fromValue((int)myMap.get("myKey")) )))

myMap 被填充了来自数据库的数据,知道这是一个 SQL Server 数据库,并且从数据库返回的 myKey 是数据库中的 tinyint 类型。

请问我做错了什么吗? 谢谢。

敬礼。


顺便提一下,EnumSet.allOf(MyEnum.class)Arrays.asList(MyEnum.values()) 更高效(更易读)。有关详细信息,请参见文档 - VGR
谢谢您的留言,我会尝试的! - niryo
3个回答

2
这里:
(int)myMap.get("myKey")

我猜测get方法返回了一个Short对象的引用,由于short没有继承自Integer,因此无法将其强制转换为Integer。
您可以将其强制转换为Short,然后调用intValue方法,像这样:
((Short)myMap.get("myKey")).intValue()

这将返回一个整数值。

谢谢,它起作用了。但我必须选择最干净的解决方案。 - niryo
谢谢!这是我案例中最好的解决方案。 - FabianoLothor

1

java.lang.ClassCastException: java.lang.Short cannot be cast to java.lang.Integer

这里的myMap.get("myKey")返回了一个Short实例,但由于该映射被声明为Map<String, Object>,所以返回的声明对象是Object

就好像你写成:

Object myValue = myMap.get("myKey")

然后,您将此声明为ObjectShort对象传递给MyEnum.fromValue(),该方法的参数为int
MyEnum.fromValue((int)myValue));

编译器试图将对象转换为Integer
但它不是一个Integer,而是一个Short
因此转换失败。
要解决问题,您应该首先检查对象的实例。
如果对象不是Short的实例,则应抛出异常或忽略该值。
如果是,您应该从Object转换为Short,并将此Short传递给fromValue(),它将自动取消包装为short
   Object myValue =  myMap.get("myKey");
   if (!(myValue instanceof Short)){          
      throw new YourRuntimeException("A Short is expected but get a " + myValue.getClass());
      // or ignore the value
   }

   if (Arrays.asList(MyEnum.values())
              .contains(MyEnum.fromValue(((short) myValue)) {
           ....
    }

谢谢,它有效。但是我写了这个小代码片段,它也有效:Short i = new Short((short) 1); int j = (int) i; System.out.println(i); 在这种情况下它是一样的,能否请您告诉我为什么?我只是想理解一下。先谢谢您了。 - niryo
原因很简单。在这里 int j = (int) i;,编译器将从 Short 拆箱为 short,然后进行从 shortint 的扩展转换。此外,强制转换对于扩展转换是无用的。int j = i; 就足够了。它仅适用于缩小转换。 在您的实际代码中,Short 实例被声明为 Object。因此,编译器不会尝试拆箱,而是直接将其转换为目标类型。我进行了编辑以解释并提供更有效的解决方案。 - davidxxx
非常感谢,我现在明白了。 - niryo

0

试试这个。

(int)(short)myMap.get("myKey")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接