Old favorite

T

Torkel Franzen

I'm looking at that showcase example of generification (from
java.util.Collections):


public static <T extends Object & Comparable<? super T>> T
min(Collection<? extends T> coll)

The reasons for the restriction on the parameter T are clear. But
given that restriction, why the wildcard in the type of coll?
Suppose we define a method

public static <T extends Object & Comparable<? super T>> T
min1(Collection<T> coll)

If T is a subtype of Comparable<S> and a subtype of S, then given
any subtype U of T, U is a subtype of Comparable<S> and a
subtype of S. So what calls go through for min but not for min1?
 
J

Jeffrey Schwab

Torkel said:
I'm looking at that showcase example of generification (from
java.util.Collections):


public static <T extends Object & Comparable<? super T>> T
min(Collection<? extends T> coll)

The reasons for the restriction on the parameter T are clear. But
given that restriction, why the wildcard in the type of coll?
Suppose we define a method

public static <T extends Object & Comparable<? super T>> T
min1(Collection<T> coll)

If T is a subtype of Comparable<S> and a subtype of S, then given
any subtype U of T, U is a subtype of Comparable<S> and a
subtype of S. So what calls go through for min but not for min1?

min1 cannot operate on collections of subtypes of T if the actual type
of T is specified explicitly. E.g., if ActualU is a subclass of
ActualT, the compiler doesn't like min1 in this situation:

ArrayList<ActualU> listOfU = new ArrayList<ActualU>();
SomeClass.<ActualT>min(listOfU);
SomeClass.<ActualT>min1(listOfU); // No good.

Here's a more complete example:

import java.util.*;

class Main {

public static void main(String[] args) {

ArrayList<CU> uList = new ArrayList<CU>( );

/* Compiler rejects min1. */
Min.<CT>min(uList);
Min.<CT>min1(uList);
}

}

class CS implements Comparable<CT> {
public int compareTo(CT ct) {
return 0;
}
}

class CT extends CS { }

class CU extends CT { }

class Min {
public static <T extends Object & Comparable<? super T>>
T min(Collection<? extends T> coll) {
return null;
}

public static <T extends Object & Comparable<? super T>>
T min1(Collection<T> coll) {
return null;
}
}
 
T

Torkel Franzen

Jeffrey Schwab said:
min1 cannot operate on collections of subtypes of T if the actual type
of T is specified explicitly.

You're right, that's a point I overlooked. We need to rely on type
inference for min1 to work.
 
T

Thomas Hawtin

Jeffrey said:
min1 cannot operate on collections of subtypes of T if the actual type
of T is specified explicitly. E.g., if ActualU is a subclass of
ActualT, the compiler doesn't like min1 in this situation:

ArrayList<ActualU> listOfU = new ArrayList<ActualU>();
SomeClass.<ActualT>min(listOfU);
SomeClass.<ActualT>min1(listOfU); // No good.

That's easy to fix:

SomeClass.<ActualU>min1(listOfU); // Good stuff.

It becomes more difficult where the collection type is using wildcards.
Here's a more complete example:

import java.util.*;

class Main {

public static void main(String[] args) {

ArrayList<CU> uList = new ArrayList<CU>( );

If that was:

List said:
/* Compiler rejects min1. */
Min.<CT>min(uList);
Fine.

Min.<CT>min1(uList);

Main.java:11: <T>min1(java.util.Collection<T>) in Min cannot be applied
to <CU>(java.util.ArrayList<capture of ? extends CU>)
CU n = Min.<CU>min1(uList);
^

Oops. Okay, we'll try to change the explicit generic argument:

CU n = Min.<? extends CU>min1(uList);

Main.java:11: illegal start of type
CU n = Min.<? extends CU>min1(uList);
^
Main.java:11: > expected
CU n = Min.<? extends CU>min1(uList);
^

I'm not entirely sure why that isn't legal, but apparently it isn't.

The only thing to do, without the Collections-style declaration, is to
remove the explicit generic argument and rely on the capture as the
first error says (can't do this for constructors, btw).

CU n = Min.min1(uList);
}

}

class CS implements Comparable<CT> {
public int compareTo(CT ct) {
return 0;
}
}

class CT extends CS { }

class CU extends CT { }

class Min {
public static <T extends Object & Comparable<? super T>>
T min(Collection<? extends T> coll) {
return null;
}

public static <T extends Object & Comparable<? super T>>
T min1(Collection<T> coll) {
return null;
}
}

Tom Hawtin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,733
Messages
2,569,439
Members
44,829
Latest member
PIXThurman

Latest Threads

Top