Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Generics With a Class & an Interface - Together

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?

like image 991
Alex Beardsley Avatar asked Apr 13 '09 23:04

Alex Beardsley


People also ask

How do you make a generic class in Java?

To update the Box class to use generics, you create a generic type declaration by changing the code "public class Box" to "public class Box<T>". This introduces the type variable, T, that can be used anywhere inside the class. As you can see, all occurrences of Object are replaced by T.

What is the use of generic methods and generic classes in Java?

Java Generic methods and generic classes enable programmers to specify, with a single method declaration, a set of related methods, or with a single class declaration, a set of related types, respectively. Generics also provide compile-time type safety that allows programmers to catch invalid types at compile time.

Can Java generics be applied to primitive types?

Using generics, primitive types can not be passed as type parameters. In the example given below, if we pass int primitive type to box class, then compiler will complain. To mitigate the same, we need to pass the Integer object instead of int primitive type.


2 Answers

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.

like image 160
Eddie Avatar answered Sep 18 '22 19:09

Eddie


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; } 
like image 41
user2861738 Avatar answered Sep 18 '22 19:09

user2861738