Wildcard Arguments

Java-Wildcard Arguments

Wildcard Arguments

There are two types of generic instantiation : concrete type instantiations and wildcard instantiations. Concrete type instantiations parameter arguments are real Java types. For example :

Wildcard Arguments
Gen<Integer> and Gen<Double> are instantiations of the generic Gen class with the concrete types Integer and Double.

Another kind of generic type instantiation is wildcard instantiation. Wildcards are Java’s way of introducing polymorphism into the type parameter portion of the generic equation. A wildcard instantiation uses a question mark (?) in place of an actual type parameter at instantiation time and denotes that the type can be assigned any of a range of possible instantiations of the generic type. The ? wildcard by itself is called the unbounded wildcard and denotes that any type instantiation is acceptable (assignable to the type). For example :

Wildcard Arguments

We declared a variable anyGen whose type is the unbounded wildcard instantiation of the generic Gen type. This means that the type we instantiated can be assigned any particular concrete instantiation of the Gen type, whether Integer, Double or Float. We assign to a Gen<Integer> first and, subsequently, a Gen<Double> or Gen<Float>. For example, consider the following generic class :

Wildcard Arguments

Assume that you want to add a method called sameTotal( ) that determines if two Gen objects contain arrays that yield the same total, no matter what type of numeric data each object holds. For example, if one object contains the double values 1.0, 2.0, 3.0, 4.0 and 5.0, and the other object contains the integer values 1, 2, 3, 4 and 5, then the total will be the same. One way to implement sameTotal( ) is to pass it a Gen argument, and then compare the total of that argument against the invoking object.

Creating sameTotal( ) seems like an easy problem. Because Gen is generic and its total( ) method can work on any type of Gen object, it seems that creating sameTotal( ) would be straightforward. Unfortunately, trouble starts as soon as you try to declare a parameter of type Gen. Because Gen is a parameterized type, what do you specify for Gen’ type parameter when you declare a parameter of that type ? At first, you might think of a solution like this, in which T is used as the type parameter :

Wildcard Arguments

The trouble with this attempt is that it will work only with other Gen  objects whose type is the same as the invoking object. For example, if the invoking object is of type Gen<Integer>, then the parameter ob must also be of type Gen<Integer>. It can’t be used to compare the total of an object of type Gen<Double> with the total of an object of type Gen<Short>

Wildcard Arguments

Therefore, this approach won’t work except in a very narrow context and does not yield a general (that is, generic) solution. To create a generic sameTotal( ) method, you must use the wildcard argument. The wildcard argument is specified by the ?, and it represents an unknown type. Using a wildcard, here is one way to write the sameTotal( ) method :

Wildcard Arguments

Gen<?> matches any Gen object, allowing any two Gen objects to have their total compared.

Program

Wildcard Arguments Wildcard Arguments

Program Source

class Gen<T extends Number> {

    T tarray[];

    Gen(T tar[]) {
        tarray = tar;
    }

    double total() {
        double total = 0;
        for (int i = 0; i < tarray.length; i++) {
            total += tarray[i].doubleValue();
        }
        return total;
    }

    void sameTotal(Gen<?> gen) {

        if (total() == gen.total()) {
            System.out.println("Totals are same");
        } else {
            System.out.println("Different totals");
        }
    }
}

public class Javaapp {

    public static void main(String[] args) {

        Gen<Integer> gen1 = new Gen<Integer>(new Integer[]{10, 20, 30, 40, 50});
        Gen<Integer> gen2 = new Gen<Integer>(new Integer[]{10, 20, 30, 40, 50});
        Gen<Double> gen3 = new Gen<Double>(new Double[]{1.1, 2.2, 3.3, 4.4, 5.5});
        Gen<Float> gen4 = new Gen<Float>(new Float[]{5.2f, 6.4f, 7.8f, 8.6f, 9.2f});

        System.out.print("gen1 and gen2 -> ");
        gen1.sameTotal(gen2);

        System.out.print("gen1 and gen3 -> ");
        gen1.sameTotal(gen3);

        System.out.print("gen1 and gen4 -> ");
        gen1.sameTotal(gen4);
    }
}

Leave a Comment