2

I am aware of that unbounded wildcard type is going to be erased and replaced with Object vy type erasure and unbounded wildcard types are the reifiable type which type information is fully available at runtime.I know difference between List<Object> , List, List<?>. I know what is the List<?> at compile time. I know that List<?> store unknown type. I know it has strong compile-time safety and flexibility but I want to know what happens in runtime.

But I cannot understand what List<?> is at runtime.

Is it list of object references? Is it raw type List?

For example

List<?> list = new ArrayList<Integer>();

What is the list at runtime and how to behave?

I read all java language specification please don't throw just an FAQ to my face.

Note that I read following Questions and I do not find my answer(can be duplicate)

Generics Java, unbounded wildcard

VGR
  • 40,506
  • 4
  • 48
  • 63
3code
  • 75
  • 6

2 Answers2

3

Well, in your example your wildcard is not unbounded.

List<?> list =new ArrayList<Integer>();

What is the list at runtime and how to behave?

At runtime, your list is an instance of ArrayList which holds Integer objects. The question you linked holds a pretty good answer about what happens when you have a wildcard. Note that the following:

List<?> list = new ArrayList<?>();

Won't compile, with the following error thrown at you:

Cannot instantiate the type ArrayList<?>

A wildcard is accepted when it comes to interfaces, but you won't be able to instantiate any object "directly" with a wildcard. You'll have to somehow, somewhere in your implementation, tell your interface what type of objects you want him to hold. Even if it means List<Object>.

Yassine Badache
  • 1,810
  • 1
  • 19
  • 38
  • Thanks.Thanks.If List> holds Integer why I can't add Integer following list?Does List> store Object references that refer to Integer?Do I get it right? – 3code Apr 11 '18 at 15:28
  • Because the compiler itself (note that you are not in runtime) won't let you do that, for numerous reasons that are beyond my scope of knowledge. I will ask the question, it is an interesting fact. – Yassine Badache Apr 11 '18 at 15:29
  • By the way, @3code, here is your answer about why can't you add Integer: https://stackoverflow.com/q/49779142/5899172 – Yassine Badache Apr 12 '18 at 07:06
-1

Generics happen mostly at compile time. The compiler uses the information in a List<String> declaration to allow list.add("Foo") and disallow with a compile-time error list.add(new Date()).

Once the compiler has proved the source code is correct, the type variables are thrown away (in a process called erasure) and in the resulting bytecode the type of the variable is simply List (neither List<?> nor List<Object>). There is no difference between a List<String> and a List<Integer> at runtime. The JVM can't tell. Only the compiler knew, and once it's compiled that information is gone forever (well, the bytecode actually knows the minimum necessary to compile new Java sources against it).

As a reference, see the implementation of ArrayList:

public class ArrayList<E> implements List<E> {
    Object[] elementData; // ← array of Object
    int size;
}

and LinkedList

public class LinkedList<E> {
    int size = 0;
    Node<E> first; // ← replaced with Node in bytecode
    private static class Node<E> {
        E item; // ← has type Object in bytecode
        Node<E> next; // ← type Node in bytecode
        Node<E> prev; // ← type Node in bytecode

        Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }
}
Raffaele
  • 20,627
  • 6
  • 47
  • 86
  • *Generics happen mostly at compile time*, well the **only** happen at compile time :) – Lino Apr 11 '18 at 14:19
  • One needs to be pragmatic but also 100% correct. Little pieces of information about the whole generics machinery survive the compiler and are written to the bytecode so that other tools (sometimes the JVM itself with reflection) can read them. – Raffaele Apr 11 '18 at 14:23
  • 1
    Thanks.I already know compile-time type safety.What does List> store at runtime?I want to retrieve an object for finding what is stored in List> by using reflection list.get(0).getClass(); but compiler safety don't allow to compile this code. – 3code Apr 11 '18 at 15:40
  • I don't know what code you are talking about, but you can't guess the type of a type variable by playing with reflection at runtime. Just imagine the case of a `List` that contains a String and an Integer – Raffaele Apr 11 '18 at 15:44
  • Thanks.How can I get I know which the type of a type variable? – 3code Apr 11 '18 at 15:56