# Unbounded Wildcard TypeS2C Home « Unbounded Wildcard Type

We saw how we can use a bounded type to get around the problem with invariance in the Bounded Type lesson.

Lets create an `UnboundedType` class based on the `BoundedType` class from the Bounded Type lesson that also compares the actual integer values of objects passed in to see if they are equal.

``````
package com.server2client;

/*
Generic type invariance
*/
public class UnboundedType<T extends Number> {  // Bounded Type

// Generic object declaration
private final T genericNumberObj;

// Pass reference to object of type T to our constructor
public UnboundedType(T genericNumberObj) {
this.genericNumberObj = genericNumberObj;
}

// Return the square of the integer
public int squareInteger() {
return genericNumberObj.intValue() * genericNumberObj.intValue();
}

// Return the square of the fraction
public double squareDouble() {
return genericNumberObj.doubleValue() * genericNumberObj.doubleValue();
}

// Return true if integer values of two objects are equal
public boolean intEqual(UnboundedType<T> obj) { // T type
return genericNumberObj.intValue() == obj.genericNumberObj.intValue();
}
}

``````

Building the `UnboundedType` class produces the following output:

The program builds fine, so now we need to write a test class to see if everything still works and we can compare integer values:

``````
package com.server2client;

/*
Test our TestUnboundedType class that only accepts Number subclasses
*/
public class TestUnboundedType {

public static void main(String[] args) {

// Test the UnboundedType class using an Integer object
UnboundedType<Integer> genIntegerObj = new UnboundedType<>(12);
System.out.println("Square of genIntegerObj is: " + genIntegerObj.squareInteger());
System.out.println("Fractional Square of genIntegerObj is: " + genIntegerObj.squareDouble());

// Test the UnboundedType class using another Integer object
UnboundedType<Integer> genIntegerObj2 = new UnboundedType<>(13);
System.out.println("Square of genIntegerObj2 is: " + genIntegerObj2.squareInteger());
System.out.println("Fractional Square of genIntegerObj2 is: " + genIntegerObj2.squareDouble());

// Test the UnboundedType class using a Double object
UnboundedType<Double> genDoubleObj = new UnboundedType<>(12.12);
System.out.println("Square of genDoubleObj is: " + genDoubleObj.squareInteger());
System.out.println("Fractional Square of genDoubleObj is: " + genDoubleObj.squareDouble());

// Test the UnboundedType class using another Double object
UnboundedType<Double> genDoubleObj2 = new UnboundedType<>(13.13);
System.out.println("Square of genDoubleObj2 is: " + genDoubleObj2.squareInteger());
System.out.println("Fractional Square of genDoubleObj2 is: " + genDoubleObj2.squareDouble());

// Test integer equality of objects
if (genIntegerObj.intEqual(genIntegerObj2)) {
System.out.println("Integer values are equal");
} else {
System.out.println("Integer values are not equal");
}
if (genDoubleObj.intEqual(genDoubleObj2)) {
System.out.println("Integer values are equal");
} else {
System.out.println("Integer values are not equal");
}
if (genIntegerObj.intEqual(genDoubleObj)) {
System.out.println("Integer values are equal");
} else {
System.out.println("Integer values are not equal");
}
}
}

``````

Building the `TestUnboundedType` class produces the following output:

As you can see from the screenshot we got a compiler error for the call to the `intEqual()` method. In the first two calls to the `intEqual()` method the invoking and parameter object are the same and so there is no problem. In the last call we have an invoking object of `Integer` and a parameter object of `Double` and as the compiler error points out we cant convert the latter bounded class type to the former. We need a way to let the compiler know that the input parameter, which we know can only be instantiated as a `Number` object or subclass thereof is an unknown type. We can achieve this by using an unbounded wildcard type, which is specified using the `?` symbol, as the input parameter to the `intEqual()` method of the `BoundedType` class.

Below is the amended code after changing the signature to `boolean intEqual(UnboundedType<?> obj)` and recompile the `UnboundedType` class.

``````
package com.server2client;

/*
Generic type invariance
*/
public class UnboundedType<T extends Number> {  // Bounded Type

// Generic object declaration
private final T genericNumberObj;

// Pass reference to object of type T to our constructor
public UnboundedType(T genericNumberObj) {
this.genericNumberObj = genericNumberObj;
}

// Return the square of the integer
public double squareInteger() {
return genericNumberObj.intValue() * genericNumberObj.intValue();
}

// Return the square of the fraction
public double squareDouble() {
return genericNumberObj.doubleValue() * genericNumberObj.doubleValue();
}

// Return true if integer values of two objects are equal
public boolean intEqual(UnboundedType<?> obj) { // Amended to unbounded wildcard type
return genericNumberObj.intValue() == obj.genericNumberObj.intValue();
}
}

``````

Running the `UnboundedType` class produces the following output:

The `UnboundedType` class now works as shown in the screenshot through our use of an unbounded wildcard type.

### Exceptions to Using Raw Types Top

Although we said earlier never use raw types there are a couple of exceptions to this rule and as a workaround for one of them is using an unbounded wildcard type this is a good place to look at them.

##### Class Literals

Generic types are not allowed in class literals, although raw types, `Array` types and primitive types are. See the Java Language Specification (JLS) 15.8.2 Class Literal for more information.

Class literal Examples
Valid Invalid
Set.class (raw type)

Integer[].class (`Array` type)

double.class (primitive type)
Set<Integer>.class

Set<?>.class
##### The `instanceof` Operator

The `instanceof` operator does now allow parameterised types due to erasure and the fact that generics are deleted at compile time.

The exception to this rule is the use of an unbounded wildcard type which can be used and is the preferred approach when using generics with the `instanceof` operator

Lets look at a code example:

``````
package com.server2client;

import java.util.ArrayList;
import java.util.List;

/*
instanceof example
*/
public class InstanceofTest {
private List<String> list = new ArrayList<>();

public static void main(String[] args) {
List<String> names = new ArrayList<>();
System.out.println(names.getClass().getName());
// Call non-static method using this class
new InstanceofTest().checkEquality(names);
}

public void checkEquality(List<String> arg) {
if (arg instanceof List<String>) {
list = arg;
}
if (list == arg) {
System.out.println("List copied and equal!");
}
}

}

``````

Building the `InstanceofTest` class produces the following output:

Below is the amended code after changing the `instanceof` operator comparison to an unbounded wildcard type.

``````
package com.server2client;

import java.util.ArrayList;
import java.util.List;

/*
instanceof example
*/
public class InstanceofTest {
private List<String> list = new ArrayList<>();

public static void main(String[] args) {
List<String> names = new ArrayList<>();
System.out.println(names.getClass().getName());
// Call non-static method using this class
new InstanceofTest().checkEquality(names);
}

public void checkEquality(List<String> arg) {
if (arg instanceof List<?>) {  // amended to unbounded wildcard type
list = arg;
}
if (list == arg) {
System.out.println("List copied and equal!");
}
}

}

``````

Running the `InstanceofTest` class produces the following output:

The `InstanceofTest` class now works as shown in the screenshot through our use of an unbounded wildcard type.

### Related Quiz

Generics Quiz 6 - Unbounded Wildcard Types Quiz

## Lesson 6 Complete

In this lesson we looked at generic unbounded wildcard types and how to use them within our classes.

## What's Next?

In the next lesson we investigate generic Upper Bounded Wildcard Type.