Community
Participate
Working Groups
Build ID: I20080617-2000 Steps To Reproduce: 1. Compile and run the following code package test; import java.rmi.RemoteException; public class aa{ private static <T extends Exception> T foo() throws T{ throw (T)new InterruptedException(); } private static void foo2() { try { RemoteException ex = foo(); } catch (RemoteException e) { e.printStackTrace(); } } public static void main( String[] args) { foo2(); } } 2. The run will throw: Exception in thread "main" java.lang.InterruptedException at test.aa.foo(aa.java:8) at test.aa.foo2(aa.java:13) at test.aa.main(aa.java:20) 3. What you got is a checked exception thrown without being declared. More information: When running JavaC from Sun JDK a compilation error is thrown: D:\aa>c:\Java\jdk1.5.0_13\bin\javac aa.java aa.java:12: exception java.rmi.RemoteException is never thrown in body of corres ponding try statement } catch (RemoteException e) { ^ aa.java:11: unreported exception T; must be caught or declared to be thrown RemoteException ex = foo(); ^ Note: aa.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details. 2 errors
The unchecked warning on offending cast (T)new InterruptedException() is telling about doing something evil. I believe the error with javac is just a bug: aa.java:11: unreported exception T; must be caught or declared to be thrown RemoteException ex = foo(); since variable T should have been inferred at this stage to be RemoteException.
Added GenericTypeTest#test1377
Marking as invalid. Closing
Got confirmation that it was a bug in javac
(In reply to comment #4) > Got confirmation that it was a bug in javac > How can it be a bug in javac this behavior is wrong... By allowing this code, you let the programmer throw checked exception from a method without declaring it.
It is a bug in javac. If you disagree with this behavior, please report a bug against the Java language specification. We simply implement it, and cannot change it unilaterally. In the context of the invocation of #foo(), no T should be presented to user, since inference should have substituted it. The bug in javac does let it surface by mistake. The fact it induces an error is accidental, and not a desired behavior. As I said earlier, the unchecked warning tells you something is unsafe, if you ignore the warning, such a runtime error is happening. This is the very reason for these warnings to be emitted.
Consider the following variation: import java.rmi.RemoteException; public class X{ private static <T extends Exception> T foo() { return (T)new InterruptedException(); } public static void main( String[] args) { RemoteException ex = foo(); } } It will compile with no error, yet throwing a ClassCastException at runtime. This time both compilers agree. Exception in thread "main" java.lang.ClassCastException: java.lang.InterruptedException cannot be cast to java.rmi.RemoteException at X.main(X.java:7)
Added GenericTypeTest#test1379
Confirmed that we behave as expected thus marking as verified for 3.5M2