Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6189041

(reflect) Add support to java.lang.Class for converting primitive wrapper types

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Duplicate
    • Icon: P4 P4
    • 5.0
    • 5.0
    • core-libs

      A DESCRIPTION OF THE REQUEST :
      There is no generic way to convert primitive types to the related wrapper type or to convert wrapper types to the contained primitive type. I propose adding the following methods to java.lang.Class:

      public boolean isWrapper ()
      public Class<?> getWrapperType ()
      public Class<?> getWrappedType ()

      isWrapper returns true for the java.lang primitive wrapper types Boolean, Byte, Short, Character, Integer, Long, Float, and Double. It returns false for all other types.

      getWrapperType returns null for all types except for the primitive types Boolean.TYPE, Byte.TYPE, Short.TYPE, Character.TYPE, Integer.TYPE, Long.TYPE, Float.TYPE, and Double.TYPE, which return the java.lang primitive wrapper types Boolean, Byte, Short, Character, Integer, Long, Float, and Double, respectively.

      getWrappedType returns null for all types except the java.lang primitive wrapper types Boolean, Byte, Short, Character, Integer, Long, Float, and Double, which return the primitive types Boolean.TYPE, Byte.TYPE, Short.TYPE, Character.TYPE, Integer.TYPE, Long.TYPE, Float.TYPE, and Double.TYPE, respectively.

      Alternative method names are:

      public boolean isPrimitiveWrapper ()
      public Class<?> getPrimitiveWrapperType ()
      public Class<?> getWrappedPrimitiveType ()

      JUSTIFICATION :
      When using reflection, primitive Field types or Method return types are returned as the corresponding wrapper class. There is currently no generic mechanism to convert between the actual type and the reflected type. This makes certain programming constructs that use reflection inelegant (see example). Since the wrapper types are integral to the Java language (even more so with the addition of auto {un}boxing), it is reasonable and useful to provide language support for the type conversion between the primitve types and their corresponding wrapper types.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      // I realize that the following simple code is not required to check for
      // Comparable Field types in the constructor and should simply allow
      // a ClassCastException to be thrown by compare, but I wanted to
      // keep the example simple.

      import java.lang.reflect.Field;
      import java.util.Comparator;

      public class GenericComparator implements Comparator, java.io.Serializable {
          private final Field field;

          public GenericComparator (Field field) {
              Class type = field.getType();
              if (type.isPrimitive())
                  type = type.getWrapper();
              if (!Comparable.class.isAssignableFrom(type))
                  throw new IllegalArgumentException("Field type must be Comparable");
              this.field = field;
          }

          public int compare (Object obj1, Object obj2) {
              try {
                  Comparable comp1 = (Comparable) field.get(obj1);
                  return comp1.compareTo(field.get(obj2));
              }
              catch (IllegalAccessException ex) {
                  throw (ClassCastException) new ClassCastException().initCause(ex);
              }
          }
      }

      ACTUAL -
      // this example demonstrates the klunky workaround currently required

      import java.lang.reflect.Field;
      import java.util.Comparator;
      import java.util.Map;
      import java.util.HashMap;

      public class GenericComparator implements Comparator, java.io.Serializable {
          private static final Map<Class, Class> WRAPPERS = new HashMap<Class, Class>();

          static {
              WRAPPERS.put(byte.class, Byte.class);
              WRAPPERS.put(short.class, Short.class);
              WRAPPERS.put(char.class, Character.class);
              WRAPPERS.put(int.class, Integer.class);
              WRAPPERS.put(long.class, Long.class);
              WRAPPERS.put(float.class, Float.class);
              WRAPPERS.put(double.class, Double.class);
              WRAPPERS.put(boolean.class, Boolean.class);
          }

          private final Field field;

          public GenericComparator (Field field) {
              Class type = field.getType();
              if (type.isPrimitive())
                  type = WRAPPERS.get(type);
              if (!Comparable.class.isAssignableFrom(type))
                  throw new IllegalArgumentException("Field type must be Comparable");
              this.field = field;
          }

          public int compare (Object obj1, Object obj2) {
              try {
                  Comparable comp1 = (Comparable) field.get(obj1);
                  return comp1.compareTo(field.get(obj2));
              }
              catch (IllegalAccessException ex) {
                  throw (ClassCastException) new ClassCastException().initCause(ex);
              }
          }
      }


      CUSTOMER SUBMITTED WORKAROUND :
      Use a Map to map between primitive types and their corresponding wrapper types and/or between wrapper types and their contained primitve types.
      ###@###.### 11/1/04 21:51 GMT

            sseligmasunw Scott Seligman (Inactive)
            gmanwanisunw Girish Manwani (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: