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 |1 Answer
Reset to default 0The 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.
out
) – greg-449 Commented Feb 6 at 10:26Integer.valueOf(s)
method that does the same asInteger.valueOf(Integer.parseInt(s))
, same for Double. – greg-449 Commented Feb 6 at 10:46