2

I've a simple generic class follows which accepts a generic type parameter, which is the same as the one declared as a type parameter of the class:

import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;

public abstract class SimpleClass<T extends AnnotatedElement>
{

   public void operate()
   {
      Method m = null;
      this.doSomething(m); // Error : SimpleClass.java:[34,10] doSomething(T) in SimpleClass<T> cannot be applied to (java.lang.reflect.Method)
   }
   protected abstract void doSomething(T annotatedElement);
}

This code fails to compile at the following line:

this.doSomething(m); 

with this error:

Error : SimpleClass.java:[34,10] doSomething(T) in SimpleClass<T> cannot be applied to (java.lang.reflect.Method)

Am I missing something here? The type parameter T is marked as T extends AnnotatedElement. As such, I would expect the call to doSomething with a java.lang.reflect.Method argument to compile successfully.

3
  • First thoughts: Method isn't a subclass of AnnotatedElement, but rather a class that implements it. Commented Mar 3, 2011 at 15:06
  • @R. Bemrose: That is irrelevant here. Commented Mar 3, 2011 at 15:13
  • @JeremyHeller: I realized that after reading the Java spec, but SO was screwing up and wouldn't let me delete that comment. Commented Mar 3, 2011 at 15:20

4 Answers 4

2

Method implements AnnotatedElement, but that doesn't require that T is a method. What if the class is declared as SimpleClass<Constructor>? That satisfies <T extends AnnotatedElement>, but doesn't support conversion from Method.

Sign up to request clarification or add additional context in comments.

5 Comments

I see what you are saying. But to take it a bit further, if I change my class and method definition to: public abstract class SimpleClass<T extends AnnotatedElement> { public void operate() { Method m = null; this.doSomething(m); // Compiles now! } protected abstract <U extends AnnotatedElement> void doSomething(U annotatedElement); } it starts compiling fine!
@Java User: That is because you are defining a method-level generic, which doesn't depend on the generic defined on the class.
Sorry about that formatting, I'm having a hard time getting it to show up correctly
and @Jeremy, thanks for explaining it. I now understand what's going on. Also, I guess I need to do some reading around generics to really wrap my head around it. Thanks again.
@Java: Yes, it compiles, but within that method, you now have two generic types: T and U, which both implement AnnotatedElement, but may or may not be related.
0

There's no way to know that T is a Method. It could just as well be e.g. a Package, and then your operate() wouldn't make sense, trying to pass a Method to something expecting Package

Comments

0

This is because T doesn't matter here. All you know is that the type is AnnotatedElement.

The following change would make it compile:

 protected abstract void doSomething(AnnotatedElement annotatedElement);

Comments

0

Your generic method is not implemented correctly. Change your generic method to

protected abstract<T extends AnnotatedElement> void doSomething(T annotatedElement);

Above statement creates correct generic method. This will remove compilation error.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.