Bad casting by type of Generics parameters does not throw a ClassCastException in Java

So, I have a pretty esoteric question. I am trying to create a somewhat general but typed data collection system. He relies on a basic assumption that seems erroneous. The code illustrates the problem:

import java.lang.Integer;

public class Test {
    private static Object mObj = new String("This should print");

    public static void main(String[] args ) {
    String s = Test.<String>get();
    System.out.println(s);

        try {
        // actual ClassCastException reported HERE
        int i = Test.<Integer>get();
    } catch ( ClassCastException e ) {
        System.out.println("Why isn't the exception caught earlier?");
        }

        int i2 = getInt();
    }

    public static <T> T get() {
    T thing = null;
    try {
        // Expected ClassCastException here
        thing = (T)mObj;
    } catch ( ClassCastException e ) {
        System.out.println("This will *not* be printed");
    }
    return thing;
    }

    // This added in the edit
    public static Integer getInt() {
    return (Integer)mObj;
    }
}

After compiling and running the output

This should print
Why isn't the exception caught earlier?

In the static "get" method, I try to use the general parameter type T. The base member (mObj) is of type String. In the first call, the Generic parameter is of a compatible type, so the application prints the string accordingly.

Generic Integer. , get . , ClassCastException ( " * * ".) , .

, get , "i". :

?

** ** getInt, , . , , .

+4
5

, get ( ) - . , T, thing = (T) mObj;, , .

- - get, Object (T, Object), :

Object thing = null;
try {
    thing = mObj;

, get, .. int i = Test.<Integer> get(); :

Object o = Test.get();
int i = ((Integer) o).intValue();
+4

, , jvm , T, Object, Integer , , : int i = Test.<Integer>get();

0

Java . , java Object.

"" - , - .

0
public static <T> T get()

, . ,

int i = Test.<Integer>get();

Integer Integer:

thing = (T)mObj;

mObj String.

0

generics, Java :

, .

ref: http://docs.oracle.com/javase/tutorial/java/generics/erasure.html

,

public static <T> T get() {
T thing = null;
try {
    // Expected ClassCastException here
    thing = (T)mObj;
} catch ( ClassCastException e ) {
    System.out.println("This will *not* be printed");
}
return thing;
}

at runtime should be deleted

public static Object get() {
Object thing = null;
try {
    // Expected ClassCastException here
    thing = (Object)mObj;
} catch ( ClassCastException e ) {
    System.out.println("This will *not* be printed");
}
return thing;
}

since T is unlimited. Understand this, then it is easy to explain the result.

0
source

All Articles