简体   繁体   English

对原始值的泛型转换导致 ClassCastException

[英]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.我在下面有一个方法根据给定的类型对 String 进行强制转换,假设给定的 String 必须是正确的。

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");但是,当我调用parsePrimitive(int.class, "10");, ,

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

This causes ClassCastException , any idea for this?这会导致ClassCastException ,对此有什么想法吗?

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. ps 事实上,当我使用 Object 作为返回类型,并且在返回之前没有强制转换时,它在方法之外工作正常,但我认为这不够通用。

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. java 编译器将生成字节码以将您的基元装箱和拆箱到对象,反之亦然,但这同样不适用于类型。

  • Boxing/Unboxing = variables装箱/拆箱 = 变量
  • Casting = types铸造=类型

In your particular case, int.class and Integer.class are not assignable from each other.在您的特定情况下, int.class 和 Integer.class 不能相互分配。

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

Output: 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.由于您必须在逻辑中进行大量专门检查,我不确定是否值得尝试提出一种将 String 解析为原始值的通用方法。

int.class is a VM internal class and not the same thing as Integer.class . int.class是 VM 内部 class 与Integer.class Here's a small snippet of code to show the differences between int.class and Integer.class.这是一小段代码,用于显示 int.class 和 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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