Method with typed list and inheritance
Asked Answered
C

2

7

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

Cowen answered 28/6, 2012 at 13:24 Comment(2)
I believe your answer lies here.Selfanalysis
Conventionally [capital V] Void is used for generic parameters you don't want to use. For instance which using java.security.PreivilegedAction without returning a value (return null - it's the only valid Void reference).Haphtarah
T
9

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.

Tame answered 28/6, 2012 at 13:39 Comment(1)
Thanks. Not really logical since we are not using T, but java's generics have some design flaws we must deal with.Cowen
F
1

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

Fancier answered 28/6, 2012 at 13:37 Comment(1)
The real problem is that I wasn't using G but a concrete class. Anyway I got my answerCowen

© 2022 - 2024 — McMap. All rights reserved.