1

There is a generic class:

class Test<T> {
    T genericTypeField;
    List<String> list;
}

void method1(Test test) {
    for (String value : test.list) { // Compiler error

    }

    // Correct
    for (Object value : test.list) {

    }
}

void method2(Test<?> test) {
    // Correct
    for (String value : test.list) {

    }
}

It seems that if use a generic class in non-generic way, all generic fields in this class will lose the generic info.

Does the Java specification has any description about this?

Yang Lifan
  • 445
  • 6
  • 15

2 Answers2

1

Type of test in method1(Test test) is a raw type.

This is the normal behaviour of Raw types in Java. It's well declared here and there. The important note for your case is:

The type of a constructor (§8.8), instance method (§8.4, §9.4), or non-static field (§8.3) M of a raw type C that is not inherited from its superclasses or superinterfaces is the raw type that corresponds to the erasure of its type in the generic declaration corresponding to C.

hoan
  • 1,058
  • 8
  • 13
  • The specific reason why this is happening is this line in the specification: "The type of a constructor (§8.8), instance method (§8.4, §9.4), or non-static field (§8.3) of a raw type C that is not inherited from its superclasses or superinterfaces is the raw type that corresponds to the erasure of its type in the generic declaration corresponding to C." – Powerlord Apr 16 '18 at 03:52
  • @Powerlord thanks for your info, updated my ans as well. – hoan Apr 16 '18 at 03:55
0

If you not provide generic type it always take as object

if you want to use string use like

   void method1(Test<String> test) {
     for (String value : test.list) { // This Compiler 
     }
   }
janith1024
  • 1,042
  • 3
  • 12
  • 25