JDK-8173884 : Runtime Generic cast issue
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 8,9
  • Priority: P4
  • Status: Closed
  • Resolution: Not an Issue
  • OS: generic
  • CPU: generic
  • Submitted: 2017-01-17
  • Updated: 2017-03-02
  • Resolved: 2017-02-03
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :


A DESCRIPTION OF THE PROBLEM :
Please check the code I submit.
Runtime generic cast should throw an exception.
And there should be a way to get the actual generic parameter type.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
We know that the future of the execution should be Future<Boolean>.
But runtime cast doesn't throw any exception.
And we are not able to know the actual generic parameter type anymore.
ACTUAL -
V
V
XXXXXXXXfalse
V
YYYYYYYYfalse

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
                Future<?> aaa = Executors.newCachedThreadPool().submit(new Callable<Boolean>() {
                    @Override
                    public Boolean call()
                    {
                        return false;
                    }
                });
                System.out.println(((ParameterizedType)aaa.getClass().getGenericInterfaces()[0]).getActualTypeArguments()[0]);
                Future<Boolean> temp = (Future<Boolean>) aaa;
                System.out.println(((ParameterizedType)temp.getClass().getGenericInterfaces()[0]).getActualTypeArguments()[0]);
                System.out.println("XXXXXXXX" + (temp == null));
                Future<Integer> temp1 = (Future<Integer>) aaa;
                System.out.println(((ParameterizedType)temp1.getClass().getGenericInterfaces()[0]).getActualTypeArguments()[0]);
                System.out.println("YYYYYYYY" + (temp1 == null));
---------- END SOURCE ----------


Comments
This is not an issue. The JVM is agnostic as to whether the Future has an Integer vs. Boolean parameterization. The only thing the VM sees is an instance of class RunnableFuture, whose superinterface is (just) Future. As a result, the VM cannot enforce correctness when performing casts involving generic types. That's the reason why programs like these are accepted with so-called 'unchecked' warnings - downcasting a Future<?> to a Future<Integer> is a potentially unsafe operation because the VM will not be able to enforce the cast at runtime and should therefore be used at your own risk. This is also related to JDK-8061418.
03-02-2017

Verified this issue against JDK 8uXX, 9ea on Windows 7 and could reproduce the issue as reported by the submitter. As a output, It should show the actual Parameter Type instead of 'V' Steps to reproduce(javac): ************************** - Run the attached file(JI_9047024.java) with JDK. Result: ******** OS: Windows 7 JDK: ****** 8 b132 : Fail 8u121 : Fail 9ea+152: Fail +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Output: ********* C:\Users\ababroy\Desktop>javac JI_9047024.java Note: JI_9047024.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details. C:\Users\ababroy\Desktop>java JI_9047024 V V XXXXXXXXfalse V YYYYYYYYfalse C:\Users\ababroy\Desktop>
03-02-2017