Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generics wildcard instantiation

I was reviewing someone else's code the other day and I came across a line that raised some concern. To simplify, say I have a generic Class A and an abstract Class B. Is the following instantiation allowed and if so, why?

Object obj = new A<? extends B>();

I personally have never seen an instantiation like the above, although a declaration such as

A<? extends B> obj = null;

would certainly hold. I've always used the wildcard in generics to declare method parameters, so I may just not have the experience.

like image 545
Josh Bradley Avatar asked Oct 06 '12 16:10

Josh Bradley


People also ask

What is the use of wildcard in generics?

In generic code, the question mark (?), called the wildcard, represents an unknown type. The wildcard can be used in a variety of situations: as the type of a parameter, field, or local variable; sometimes as a return type (though it is better programming practice to be more specific).

What are the type s of wildcards in generics?

There are 3 types of wildcards in Java: Upper bounded wildcards, Lower Bounded Wildcards, and Unbounded Wildcards.

Can you instantiate a generic type?

To use Java generics effectively, you must consider the following restrictions: Cannot Instantiate Generic Types with Primitive Types. Cannot Create Instances of Type Parameters.

What is bounded and unbounded wildcards in generics Java?

both bounded and unbounded wildcards provide a lot of flexibility on API design especially because Generics is not covariant and List<String> can not be used in place of List<Object>. Bounded wildcards allow you to write methods that can operate on Collection of Type as well as Collection of Type subclasses.


1 Answers

Actually new A<? extends B>() does not compile. It has been consistently illegal since Java 5.

But I guess your original example was something like new A<X<? extends B>>(). The latter is legal in recent versions of Java.

The idea is, when instantiating an object, the value for type parameters can be any non-wildcard type. ? extends B is a wildcard type, so it is disallowed. But X<? extends B> is not a wildcard type, though it has a wildcard type as a component. So you can say legally call new A<X<? extends B>>().

The rules makes sense if you think about it this way. Ultimately it is a byproduct of the more fundamental rule that a wildcard type like ? extends B cannot be the declared type of a field or variable. If A is defined as

class A<T> {
    T value;
}

then the hypothetical new A<? extends B>().value would be a field declared of type ? extends B. Since that is illegal, so is the instantiation. But new A<X<? extends B>>() does not have that problem.

like image 119
Saintali Avatar answered Sep 21 '22 13:09

Saintali