Web Hosting Web Hosting, web hosting, JSP, Servlets, Tomcat, website hosting, web site hosting
Web Hosting, web hosting, JSP, Servlets, Tomcat, website hosting, web site hosting
Web Hosting, web hosting, JSP, Servlets, Tomcat, website hosting, web site hosting

Alden Hosting provides professional, efficient, and reliable business-class Web hosting services to small- and medium-sized businesses.


Call Us Toll-Free
(877) 256-0328

Outside USA
1 - (201) 505-0430

Web Hosting Welcome Web Hosting Web Hosting Plans Overview , Fund Raising, Fundraising, web hosting, website hosting, web site hosting Web Hosting Fund Raising, Fundraising, web hosting Web Hosting Resellers, web Hosting Web Hosting Web Design, web Hosting Web Hosting Extra Services,  web Hosting Web Hosting Traffic Booster, web hosting Web Hosting Traffic Booster, web hosting Web Hosting Technical Support,  web Hosting Web Hosting webmaster tips,  web Hosting Web Hosting 30 Day Money Back, web hosting Web Hosting Legal Notices for Web Hosting Web Hosting Glossary Computer Terms for web Hosting Web Hosting Contact Information - web hosting

Site Map

  Web Hosting Web Hosting Sign-Up   Web Hosting Fund Raising, Fundraising, web hosting, website hosting, web site hosting    Web Hosting Resellers web hosting, website hosting, web site hosting   Web Hosting EZ Site Control Panel for web hosting,website hosting, web site hosting
More Fun with Wildcards (The Java™ Tutorials > Bonus > Generics)
Trail: Bonus
Lesson: Generics
Home Page > Bonus > Generics
More Fun with Wildcards
In this section, we'll consider some of the more advanced uses of wildcards. We've seen several examples where bounded wildcards were useful when reading from a data structure. Now consider the inverse, a write-only data structure. The interface Sink is a simple example of this sort.
interface Sink<T> {
    flush(T t);
We can imagine using it as demonstrated by the code below. The method writeAll() is designed to flush all elements of the collection coll to the sink snk, and return the last element flushed.
public static <T> T writeAll(Collection<T> coll, Sink<T> snk) {
    T last;
    for (T t : coll) {
        last = t;
    return last;
Sink<Object> s;
Collection<String> cs;
String str = writeAll(cs, s); // Illegal call.
As written, the call to writeAll() is illegal, as no valid type argument can be inferred; neither String nor Object are appropriate types for T, because the Collection element and the Sink element must be of the same type.

We can fix this error by modifying the signature of writeAll() as shown below, using a wildcard.

public static <T> T writeAll(Collection<? extends T>, Sink<T>) {...}
String str = writeAll(cs, s); // Call is OK, but wrong return type. 
The call is now legal, but the assignment is erroneous, since the return type inferred is Object because T matches the element type of s, which is Object.

The solution is to use a form of bounded wildcard we haven't seen yet: wildcards with a lower bound. The syntax ? super T denotes an unknown type that is a supertype of T (or T itself; remember that the supertype relation is reflexive). It is the dual of the bounded wildcards we've been using, where we use ? extends T to denote an unknown type that is a subtype of T.

public static <T> T writeAll(Collection<T> coll, Sink<? super T> snk) {
String str = writeAll(cs, s); // Yes! 
Using this syntax, the call is legal, and the inferred type is String, as desired.

Now let's turn to a more realistic example. A java.util.TreeSet<E> represents a tree of elements of type E that are ordered. One way to construct a TreeSet is to pass a Comparator object to the constructor. That comparator will be used to sort the elements of the TreeSet according to a desired ordering.

TreeSet(Comparator<E> c) 
The Comparator interface is essentially:
interface Comparator<T> {
    int compare(T fst, T snd);
Suppose we want to create a TreeSet<String> and pass in a suitable comparator, We need to pass it a Comparator that can compare Strings. This can be done by a Comparator<String>, but a Comparator<Object> will do just as well. However, we won't be able to invoke the constructor given above on a Comparator<Object>. We can use a lower bounded wildcard to get the flexibility we want:
TreeSet(Comparator<? super E> c) 
This code allows any applicable comparator to be used.

As a final example of using lower bounded wildcards, lets look at the method Collections.max(), which returns the maximal element in a collection passed to it as an argument. Now, in order for max() to work, all elements of the collection being passed in must implement Comparable. Furthermore, they must all be comparable to each other.

A first attempt at generifying this method signature yields:

public static <T extends Comparable<T>> 
        T max(Collection<T> coll)
That is, the method takes a collection of some type T that is comparable to itself, and returns an element of that type. However, this code turns out to be too restrictive. To see why, consider a type that is comparable to arbitrary objects:
class Foo implements Comparable<Object> {
Collection<Foo> cf = ... ;
Collections.max(cf); // Should work.
Every element of cf is comparable to every other element in cf, since every such element is a Foo, which is comparable to any object, and in particular to another Foo. However, using the signature above, we find that the call is rejected. The inferred type must be Foo, but Foo does not implement Comparable<Foo>.

It isn't necessary that T be comparable to exactly itself. All that's required is that T be comparable to one of its supertypes. This give us:

public static <T extends Comparable<? super T>> 
        T max(Collection<T> coll)
Note that the actual signature of Collections.max() is more involved. We return to it in the next section, Converting Legacy Code to Use Generics. This reasoning applies to almost any usage of Comparable that is intended to work for arbitrary types: You always want to use Comparable<? super T>.

In general, if you have an API that only uses a type parameter T as an argument, its uses should take advantage of lower bounded wildcards (? super T). Conversely, if the API only returns T, you'll give your clients more flexibility by using upper bounded wildcards (? extends T).

Wildcard Capture

It should be pretty clear by now that given:
Set<?> unknownSet = new HashSet<String>();
/** Add an element  t to a Set s. */ 
public static <T> void addToSet(Set<T> s, T t) {
The call below is illegal.
addToSet(unknownSet, "abc"); // Illegal.
It makes no difference that the actual set being passed is a set of strings; what matters is that the expression being passed as an argument is a set of an unknown type, which cannot be guaranteed to be a set of strings, or of any type in particular.

Now, consider the following code:

class Collections {
    <T> public static Set<T> unmodifiableSet(Set<T> set) {
Set<?> s = Collections.unmodifiableSet(unknownSet); // This works! Why?
It seems this should not be allowed; yet, looking at this specific call, it is perfectly safe to permit it. After all, unmodifiableSet() does work for any kind of Set, regardless of its element type.

Because this situation arises relatively frequently, there is a special rule that allows such code under very specific circumstances in which the code can be proven to be safe. This rule, known as wildcard capture, allows the compiler to infer the unknown type of a wildcard as a type argument to a generic method.

Previous page: Class Literals as Runtime-Type Tokens
Next page: Converting Legacy Code to Use Generics
Web Hosting, web hosting, JSP, Servlets, Tomcat, website hosting, web site hosting
Add to My Yahoo!

XML icon

Add to Google












JSP at alden-servlet-Hosting.com
Servlets at alden-servlet-Hosting.com
Servlet at alden-servlet-Hosting.com
Tomcat at alden-servlet-Hosting.com
MySQL at alden-servlet-Hosting.com
Java at alden-servlet-Hosting.com
sFTP at alden-servlet-Hosting.com
JSP at alden-tomcat-Hosting.com
Servlets at alden-tomcat-Hosting.com
Servlet at alden-tomcat-Hosting.com
Tomcat at alden-tomcat-Hosting.com
MySQL at alden-tomcat-Hosting.com
Java at alden-tomcat-Hosting.com
sFTP at alden-tomcat-Hosting.com
JSP at alden-sftp-Hosting.com
Servlets at alden-sftp-Hosting.com
Servlet at alden-sftp-Hosting.com
Tomcat at alden-sftp-Hosting.com
MySQL at alden-sftp-Hosting.com
Java at alden-sftp-Hosting.com
sFTP at alden-sftp-Hosting.com
JSP at alden-jsp-Hosting.com
Servlets at alden-jsp-Hosting.com
Servlet at alden-jsp-Hosting.com
Tomcat at alden-jsp-Hosting.com
MySQL at alden-jsp-Hosting.com
Java at alden-jsp-Hosting.com
sFTP at alden-jsp-Hosting.com
JSp at alden-java-Hosting.com
Servlets at alden-java-Hosting.com
Servlet at alden-java-Hosting.com
Tomcat at alden-java-Hosting.com
MySQL at alden-java-Hosting.com
Java at alden-java-Hosting.com
sFTP at alden-java-Hosting.com
JSP Servlets Tomcat mysql Java JSP Servlets Tomcat mysql Java JSP Servlets Tomcat mysql Java JSP Servlets Tomcat mysql Java JSP at JSP.aldenWEBhosting.com Servlets at servlets.aldenWEBhosting.com Tomcat at Tomcat.aldenWEBhosting.com mysql at mysql.aldenWEBhosting.com Java at Java.aldenWEBhosting.com Web Hosts Portal Web Links Web Links Web Hosting JSP Solutions Web Links JSP Solutions Web Hosting Servlets Solutions Web Links Servlets Solutions Web Hosting Web Links Web Links . .
. .
. . . . jsp hosting servlets hosting web hosting web sites designed cheap web hosting web site hosting myspace web hosting