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

Field "protected T[] data" has issues in subclasses.

    XMLWordPrintable

    Details

      Description

      A DESCRIPTION OF THE PROBLEM :
      If we define a generic class A<T> { protected T[] data; } and then define a non generic subclass B extends A<SomeClass>, then we cannot have acces to protected data[] field in subclass B without an explicit conversion data[] to Object[]. In statements like Object o = data[1] in subclasses a ClassCastException is thrown.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      I don't know if this is a bug or not but a workaround seems to be weird. The statement Object o = data[1] must run without errors I think.

      ---------- BEGIN SOURCE ----------
      class Thing {}

      class A<T> {

      protected T[] data;

      public A(int size) {
      this.data = (T[])new Object[size];
      }

      public T get(int index) {
      System.out.println("A.get() = " + data[index]);
      return data[index];
      }

      public void set(int index, T element) {
      data[index] = element;
      }

      public void m0(int index) {
      Object o = data[index];//it's OK, no exceptions
      }

      }

      class B extends A<Thing> {

      public B(int size) {
      super(size);
      }

      public void m1(int index) {
      Object o = data[index];//throws ClassCastException
      }

      public void m2(int index) {
      Object o = ((Object[])data)[index];//doesn't throw ClassCastException
      }

      public void m3(int index) {
      Thing th = ((Thing[])data)[index];//throws ClassCastException
      }

      public void m4(int index) {
      Thing th = (Thing)((Object[])data)[index];//doesn't throw ClassCastException
      }

      }

      public class WeirdClassCastExceptionError {

      public static void main(String[] ars) {
      B b = new B(16);
      int index = 3;
      b.set(index, new Thing());
      System.out.println("Element at index " + index + " : " + b.get(index));
      b.m0(index);//no exception
      b.m1(index);//ClassCastException
      b.m2(index);//no exception
      // b.m3(index);//ClassCastException
      b.m4(index);//no exception
      // b.data[1] = new Object();//doesn't compile, parameterized type error
      // b.data[5] = new Thing();//ClassCastException
      ((Object[])b.data)[5] = new Thing();//no exception
      Thing th;
      // th = b.data[5];//ClassCastException
      th = (Thing)((Object[])b.data)[5];//no exception
      }

      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      We must explicit cast the array T[] data to Object[] then retrieve an element by index and then cast that element to T. In that way we can have acces to the elements of the field "protected T[] data" of a generic super class.

        Attachments

          Activity

            People

            Assignee:
            tongwan Andrew Wang
            Reporter:
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved: