Why is it T extends Comparable and not T implements Comparable ?
Simply put: Java does not make a distinction between interfaces and classes when defining bounds for generic type parameters. extends
is used for both interface and class types which makes expressing the bound direction (link added from Sambits comment on the main post) more streamlined.
implements vs extends in generics in Java
The difference is pretty straightforward: second code snippet does not compile and never will. With generics you always use extends
, for both classes and interfaces. Also super
keyword can be used there, but it has different semantics.
Check if a generic T implements an interface
Generics, oddly enough, use extends
for interfaces as well.1 You'll want to use:
public class Foo<T extends SomeInterface>{
//use T as you wish
}
This is actually a requirement for the implementation, not a true/false check.
For a true/false check, use unbounded generics(class Foo<T>{
) and make sure you obtain a Class<T>
so you have a refiable type:
if(SomeInterface.class.isAssignableFrom(tClazz));
where tClazz
is a parameter of type java.lang.Class<T>
.
If you get a parameter of refiable type, then it's nothing more than:
if(tParam instanceof SomeInterface){
but this won't work with just the generic declaration.
1If you want to require extending a class and multiple interfaces, you can do as follows: <T extends FooClass & BarInterface & Baz>
The class(only one, as there is no multiple inheritance in Java) must go first, and any interfaces after that in any order.
When do Java generics require ? extends T instead of T and is there any downside of switching?
First - I have to direct you to http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html -- she does an amazing job.
The basic idea is that you use
<T extends SomeClass>
when the actual parameter can be SomeClass
or any subtype of it.
In your example,
Map<String, Class<? extends Serializable>> expected = null;
Map<String, Class<java.util.Date>> result = null;
assertThat(result, is(expected));
You're saying that expected
can contain Class objects that represent any class that implements Serializable
. Your result map says it can only hold Date
class objects.
When you pass in result, you're setting T
to exactly Map
of String
to Date
class objects, which doesn't match Map
of String
to anything that's Serializable
.
One thing to check -- are you sure you want Class<Date>
and not Date
? A map of String
to Class<Date>
doesn't sound terribly useful in general (all it can hold is Date.class
as values rather than instances of Date
)
As for genericizing assertThat
, the idea is that the method can ensure that a Matcher
that fits the result type is passed in.
How come generic type parameter says extends Comparable not implements ?
If You want to use the thing that implements You just write is as generic parameter
class Bar extends Foo<String> { /* Code */}
The wildcard that You are talking about are three
- "? extends Type": Denotes a family of subtypes of type Type. This
is the most useful wildcard- "? super Type": Denotes a family of supertypes of type Type
- "?": Denotes the set of all types or any
You method should look like
public static <T extends Comparable<? super T>> Collection<T> sort(T[] list) {
Collection<T> list = new ArrayList<T>();
//do quicksort
Arrays.sort(arr);
Collection<T> list = new ArrayList<T>();
int i;
for(i=0; i<arr.length-1; i++) {
if(arr[i].compareTo(arr[i+1]) != 0) { //if not duplicate, add to the list
list.add(arr[i]);
}
}
list.add(arr[i]); //add last element
//btw how do You know that last is not duplicate
return list;
}
For detail please visit this page
Why can't a Java Generic implement an Interface?
The extends
keyword applies to interfaces too. That is:
public class SinglyLinkedList<E extends HasName> {
Means that E
must be a type that extends a class, or implements an interface, called HasName
.
It is not possible to code E implements HasName
- that is implied by E extends HasName
.
Related Topics
How Can a String Be Initialized Using " "
Eventlistenerlist Firing Order
Why Is the Clone() Method Protected in Java.Lang.Object
Why Does This Java Method Appear to Have Two Return Types
Get Width and Height of JPAnel Outside of the Class
Java.Util.Date Format Conversion Yyyy-Mm-Dd to Mm-Dd-Yyyy
Cannot Make a Static Reference to the Non-Static Field
How to Use a Wildcard in the Classpath to Add Multiple Jars
Multiple Line Code Example in Javadoc Comment
Java: How to Split an Arraylist in Multiple Small Arraylists
Eclipse 2021-09 Code Completion Not Showing All Methods and Classes
Using Heapdumponoutofmemoryerror Parameter for Heap Dump for Jboss
Concurrentmodificationexception Despite Using Synchronized
Java Thread.Sleep Puts Swing UI to Sleep Too