I want to have a Class object, but I want to force whatever class it represents to extend class A and implement interface B.
I can do:
Class<? extends ClassA>
Or:
Class<? extends InterfaceB>
but I can't do both. Is there a way to do this?
I want to have a Class object, but I want to force whatever class it represents to extend class A and implement interface B.
I can do:
Class<? extends ClassA>
Or:
Class<? extends InterfaceB>
but I can't do both. Is there a way to do this?
Actually, you can do what you want. If you want to provide multiple interfaces or a class plus interfaces, you have to have your wildcard look something like this:
<T extends ClassA & InterfaceB>
See the Generics Tutorial at sun.com, specifically the Bounded Type Parameters section, at the bottom of the page. You can actually list more than one interface if you wish, using & InterfaceName
for each one that you need.
This can get arbitrarily complicated. To demonstrate, see the JavaDoc declaration of Collections#max
, which (wrapped onto two lines) is:
public static <T extends Object & Comparable<? super T>> T
max(Collection<? extends T> coll)
why so complicated? As said in the Java Generics FAQ: To preserve binary compatibility.
It looks like this doesn't work for variable declaration, but it does work when putting a generic boundary on a class. Thus, to do what you want, you may have to jump through a few hoops. But you can do it. You can do something like this, putting a generic boundary on your class and then:
class classB { }
interface interfaceC { }
public class MyClass<T extends classB & interfaceC> {
Class<T> variable;
}
to get variable
that has the restriction that you want. For more information and examples, check out page 3 of Generics in Java 5.0. Note, in <T extends B & C>
, the class name must come first, and interfaces follow. And of course you can only list a single class.
T extends Object
part ? –
Cerecloth ?
in that expression, so is it really a "wildcard"? I ask because I can't get the whole "extending two things at once" concept to work when the type parameter really is a wildcard. –
Bobbyebobbysocks class GrandSon extends Child
, class GrandDaughter extends Child
, class Child extends Parent
. How do I declare GrandChildrenTask<T extends <? extends Parent>>
. Note that Child and its subclasses are unknown, only Parent is available in library. –
Heartburning T extends from something that extends Parent
. In that case, since inheritance is transitive, all you need is T extends Parent
. Also, you cannot distinguish the level of inheritance. So here, both Child
and GrandSon
are equally valid. –
Boxhaul GrandSon
to be passed and not Child
, then there must be something special in GrandSon
. In that case, you can just specify it like T extends Parent & Grandness
. –
Boxhaul ?
? Like people have pointed out before. I thought that I could just go ahead with ?
but then got really confused. Only the next answer here told me that ?
won’t work for some reason. Also the “the class name must come first” limitation should be mentioned in the first paragraph, in my opinion. –
Placebo You can't do it with "anonymous" type parameters (ie, wildcards that use ?
), but you can do it with "named" type parameters. Simply declare the type parameter at method or class level.
import java.util.List;
interface A{}
interface B{}
public class Test<E extends B & A, T extends List<E>> {
T t;
}
© 2022 - 2024 — McMap. All rights reserved.