JDK-6520205 : (enum) Enum constructor has wrong generic parameter types
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 5.0
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: solaris_2.5.1
  • CPU: x86
  • Submitted: 2007-02-01
  • Updated: 2024-04-12
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdUnresolved
Related Reports
Relates :  
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.5.0_09"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_09-b03)
Java HotSpot(TM) Server VM (build 1.5.0_09-b03, mixed mode)

and

java version "1.6.0"
Java(TM) SE Runtime Environment (build 1.6.0-b105)
Java HotSpot(TM) Server VM (build 1.6.0-b105, mixed mode)


A DESCRIPTION OF THE PROBLEM :
Using the reflection API to look at the parameter types for the synthetic enum
constructor produces different results depending upon whether
getParameterTypes() or getGenericParameterTypes() is used.

I'm guessing it is related to this?
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4989987

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
See the testcase

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The methods getParameterTypes() and getGenericParameterTypes()
should provide the same results (at least arrays of the same size).
ACTUAL -
The getGenericParameterTypes() returns an empty array of parameter types.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
package test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Type;
import java.util.Arrays;

public class Main
{
   public static void main(String[] args) throws Exception
   {
      Class<MyEnum> clazz = MyEnum.class;
      Constructor<MyEnum> constructor = clazz.getDeclaredConstructor(new Class[] { String.class, Integer.TYPE });
      Type[] types = constructor.getParameterTypes();
      Type[] generic = constructor.getGenericParameterTypes();
      System.out.println("types   = " + Arrays.asList(types));
      System.out.println("generic = " + Arrays.asList(generic));
      if (Arrays.equals(types, generic) == false)
         throw new RuntimeException("They should be the same?");
   }
   
   public enum MyEnum { ONE, TWO, THREE };
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
A simple workaround is the following code,
but only if you know the problem exists and can assume
the problem is for types that don't use generic parameters?

// Use the normal types if the generic types are inconsistent
Type[] types = constructor.getParameterTypes();
Type[] generic = constructor.getGenericParameterTypes();
if (types.length != generic.length)
   generic = types;

Comments
The mismatch between getParameterTypes() and getGenericParameterTypes() is now intended, but the issue with getParameters()[index].getParameterizedType() is still present: import java.lang.reflect.*; import java.util.*; public enum Foo { ; Foo(Optional<String> st) {} public static void main(String[] args) throws Exception { var ctor = Foo.class.getDeclaredConstructor(String.class, int.class, Optional.class); System.out.println(ctor.getParameters()[2].getParameterizedType()); } } Notice it prints class java.util.Optional instead of a parameterized type like java.util.Optional<java.lang.String>
28-04-2023

The information now available after JDK-8004729 should help resolve this issue.
14-08-2013

EVALUATION There are inconsistencies here, but addressing them is a bit tricky. Core reflection more or less presents a class file view of the world while the getGenericFoo methods present a source file view of the world if generic information is present. Differences can appear between these two views in cases such as the synthetic parameters added by javac to the enum constructors.
02-02-2007