简体   繁体   中英

Generic Casting on primitive value causing ClassCastException

I have a method below doing casting on a String according to the given type, assuming the String given must be correct.

private static <T> T parsePrimitive(final Class<T> primitiveType, final String primitiveValue) {
    if (primitiveType.equals(int.class) || primitiveType.equals(Integer.class)) {
        return primitiveType.cast(Integer.parseInt(primitiveValue));
    }
    /*
    ...
    for the rest of the primitive type
    ...
    */
}

However, when I call parsePrimitive(int.class, "10");,

primitiveType.cast(Integer.parseInt(primitiveValue));

This causes ClassCastException , any idea for this?

ps In fact, when I use Object as the return type, and no casting in before return, it works fine outside the method, but this is not generic enough I think.

Thanks in advance for any help.

You are mixing up autoboxing and casting. The java compiler will generate bytecode to box and unbox your primitives to objects and vice versa, but the same does not apply to types.

  • Boxing/Unboxing = variables
  • Casting = types

In your particular case, int.class and Integer.class are not assignable from each other.

Class<?> intClazz = int.class;
Class<?> integerClazz = Integer.class;
System.out.println(intClazz);
System.out.println(integerClazz);
System.out.println(integerClazz.isAssignableFrom(intClazz));

Output:

int
class java.lang.Integer
false

With the amount of specialized checks you would have to put in your logic I am not sure its worth trying to come up with a generic method for parsing a String into a primitive value.

int.class is a VM internal class and not the same thing as Integer.class . Here's a small snippet of code to show the differences between int.class and Integer.class.

import java.lang.reflect.Modifier;
import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        dump(int.class);
        System.out.println("---");
        dump(Integer.class);
    }

    private static void dump(Class<?> c) {
        System.out.printf(
            "Name: %s%n" +
            "Superclass: %s%n" +
            "Interfaces: %s%n" +
            "Modifiers: %s%n",
            c.getName(),
            c.getSuperclass() == null ? "null" : c.getSuperclass().getName(),
            Arrays.asList(c.getInterfaces()),
            Modifier.toString(c.getModifiers()));
    }
}

Outputs:

Name: int
Superclass: null
Interfaces: []
Modifiers: public abstract final
---
Name: java.lang.Integer
Superclass: java.lang.Number
Interfaces: [interface java.lang.Comparable]
Modifiers: public final

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM