質問

I have some troubles with a method having a typed List parameter, inherited from another (typed) class.

Let's keep it simple :

public class B<T> {
  public void test(List<Integer> i) {
  }
}

The B class has a useless generic T, and test() want an Integer List.

Now if I do :

public class A extends B {
  // don't compile
  @Override
  public void test(List<Integer> i) {
  }
}

I get a "The method test(List) of type A must override or implement a supertype method" error, that should not happen.

But removing the type of the list works... although it doesn't depend on the class generic.

public class A extends B {
  // compile
  @Override
  public void test(List i) {

And also defining the useless generic below to use the typed list

public class A extends B<String> {
  // compile
  @Override
  public void test(List<Integer> i) {

So I'm clueless, the generic of B should have no influence on the type of the test() list. Does anyone have an idea of what's happening?

Thanks

役に立ちましたか?

解決

You're extending the raw type of B, not the generic one. The raw one effectively does not have a test(List<Integer> i) method, but a test(List) method.

If you switch to raw types, all generics are replaced by raws, regardless of whether their type was filled in or not.

To do it properly, do

 public class A<T> extends B<T>

This will use the generic type B<T>, which includes the method you want to override.

他のヒント

When you remove use a class without generics (and use it raw), all generics from class methods are forgotten.

Due this reason when you inform the generic type on the second case you get it working.

This:

class T<G> {
   public void test(G g);
}

in this case:

class A extends T {
}

will look like this:

class T {
   public void test(Object g);
}

This was a java puzzle presented on Google IO 2011 you can see video here

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top