最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

java - Casting object to generic type - Stack Overflow

programmeradmin1浏览0评论

I wonder why the following program works. In particular, why an exception is not thrown (see comment in code).

public class A {
    public static <U> U m(String s){
        U out=null;
        try {
            out = (U) Integer.valueOf(Integer.parseInt(s));
        } catch (NumberFormatException e){
            System.out.println("ex int ");
        }
        if(out==null)
            try {
                out = (U) Double.valueOf(Double.parseDouble(s));
            } catch (NumberFormatException e){
                System.out.println("ex double");
            }
        System.out.println(out.getClass().getName());
        return out;
    }

    public static void main(String[] args) {
        String s = new String("10.2");
        System.out.println(A.<Integer>m(s)); // Shouldn't the compiler generate a warning at this point?
        
    }
}

Similar topics have already been discussed (for example: Cast Object to Generic Type for returning). I understood that due to type erasure the compiled code will match:

Object out = (Object) Double.valueOf(Double.parseDouble(s));

but isn't it the role of the compiler to detect incorrect type casting?

I wonder why the following program works. In particular, why an exception is not thrown (see comment in code).

public class A {
    public static <U> U m(String s){
        U out=null;
        try {
            out = (U) Integer.valueOf(Integer.parseInt(s));
        } catch (NumberFormatException e){
            System.out.println("ex int ");
        }
        if(out==null)
            try {
                out = (U) Double.valueOf(Double.parseDouble(s));
            } catch (NumberFormatException e){
                System.out.println("ex double");
            }
        System.out.println(out.getClass().getName());
        return out;
    }

    public static void main(String[] args) {
        String s = new String("10.2");
        System.out.println(A.<Integer>m(s)); // Shouldn't the compiler generate a warning at this point?
        
    }
}

Similar topics have already been discussed (for example: Cast Object to Generic Type for returning). I understood that due to type erasure the compiled code will match:

Object out = (Object) Double.valueOf(Double.parseDouble(s));

but isn't it the role of the compiler to detect incorrect type casting?

Share Improve this question asked Feb 6 at 10:16 tomkutomku 11 bronze badge New contributor tomku is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct. 4
  • "isn't it the role of the compiler to detect incorrect type casting": yes, and it does. Compiling this without -Xlint:unchecked encourages you to compile with -Xlint:unchecked, and then you should get two warnings of "warning: [unchecked] unchecked cast" – Jon Skeet Commented Feb 6 at 10:20
  • Eclipse gives me "Type safety: Unchecked cast from Integer/Double to U" warnings on the casts (and a "Potential null pointer access: The variable out may be null at this location" warning when you print out) – greg-449 Commented Feb 6 at 10:26
  • As an aside note that is a Integer.valueOf(s) method that does the same as Integer.valueOf(Integer.parseInt(s)), same for Double. – greg-449 Commented Feb 6 at 10:46
  • Thank you. Indeed, compilation with this option ends with the expected warnings. – tomku Commented Feb 6 at 10:50
Add a comment  | 

1 Answer 1

Reset to default 0

The compiler won't generate a warning at System.out.println(A.<Integer>m(s)); because there's nothing wrong there. The method has a generic type, and you're telling the compiler that the type is Integer. The compiler doesn't know that something can be wrong here.

The warnings you want can be found here:

out = (U) Integer.valueOf(Integer.parseInt(s));

and

out = (U) Double.valueOf(Double.parseDouble(s));

Both are unchecked casts because there's no actual casting. That casting won't occur until you do this:

Integer i = A.m(s);
Double d = A.m(s);

Unless s cannot be parsed to Integer or Double (and the result will be null), one of those will definitely throw a ClassCastException because of the unchecked casts inside the method.

发布评论

评论列表(0)

  1. 暂无评论