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

12,178

Solution 1

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

Here myMap.get("myKey") returns a Short instance but the returned declared object is Object as the map is declared Map<String, Object>.

It is as if you had written :

Object myValue = myMap.get("myKey")

Then you pass this Short object declared as Object to MyEnum.fromValue() that has as parameter an int.

MyEnum.fromValue((int)myValue));

The compiler tries so to cast the object to an Integer.
But it is not an Integer but a Short.
So the cast fails.

To solve your problem, you should first check the instance of your object.
If the object is not an instance of Short, you should throw an exception or ignore the value.
If it is, you should cast from Object to Short and pass this Short to fromValue() that will be automatically unboxed to 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)) {
           ....
    }

Solution 2

Here :

(int)myMap.get("myKey")

I guess that the get method returned a reference to a Short object, which can't be cast to Integer, since short doesn't inherit from Integer.

What you can do is casting to Short, then call the intValue method, like this :

((Short)myMap.get("myKey")).intValue()

Which will return a integer value

Share:
12,178

Related videos on Youtube

niryo
Author by

niryo

Updated on June 04, 2022

Comments

  • niryo
    niryo almost 2 years

    In my project I have an Enum like this :

    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;
    }
    

    And I have this code :

    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
        }
    

    I get the Exception

     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 is filled with data from database, knowing that it is an SQL Server Database and that the myKey returned from database is of type tinyint in the database.

    Can you please tell me what I am doing wrong ? Thanks.

    Regards.

    • VGR
      VGR almost 7 years
      By the way, EnumSet.allOf(MyEnum.class) is far more efficient (and easier to read) than Arrays.asList(MyEnum.values()). See the documentation for more information.
    • niryo
      niryo almost 7 years
      Thanks for the comment, i'll try that !
  • niryo
    niryo almost 7 years
    thanks, it worked. But I had to choose the cleanest solution
  • niryo
    niryo almost 7 years
    Thank you it works. However I've written this little part of code which works : Short i = new Short((short) 1); int j = (int) i; System.out.println(i); . It's the same thing and it works in this case, can you please tell me why ? I'm just trying to understand. Thank you in advance.
  • davidxxx
    davidxxx almost 7 years
    The reason is simple. Here int j = (int) i; the compiler unboxes i value from Short to short and then does a widening conversion from short to int. Besides the cast is useless for widening conversion. int j = i; is enough. It is required only for narrowing conversion. In your actual code, the Short instance is declared as Object. So the compiler doesn't try to unbox it but do directly a cast to the target cast. I edited to explain it and provide a still more effective solution.
  • niryo
    niryo almost 7 years
    Thank you very much, I understand now.
  • FabianoLothor
    FabianoLothor about 6 years
    Thanks! This is the best solution from my case.