-2

From https://stackoverflow.com/a/31876747

In Java generics, a generic type definition is transformed to essentially one concrete generic type shared across all allowed type argument combinations. Thus, multiple (source code level) types are mapped to one (binary level) type - but as a result, information about the type arguments of an instance is discarded in that instance (type erasure).

Type information that could have been available at runtime (using reflection) is lost. This, in turn, means that specialization of a generic type (the ability to use specialized source code for any particular generic argument combination) is very restricted.

What are the consequences of "Type information that could have been available at runtime (using reflection) is lost"?

What does it means by "specialization of a generic type (the ability to use specialized source code for any particular generic argument combination) is very restricted"?

Maybe some examples?

Thanks.

Community
  • 1
  • 1
Tim
  • 1
  • 141
  • 372
  • 590
  • Not exactly a duplicate and on a different site but has many good answers https://softwareengineering.stackexchange.com/questions/22642/what-is-wrong-with-javas-generics – Oleg Sep 18 '17 at 02:46

1 Answers1

2

I will start with a simple example called GenericTest. This class tries to find the type of parameters used in the ArrayList.

public class GenericTest {

    // Result would be the same if I have used wildcard (?) instead,
    // public static void findType(ArrayList<?> list)
    public static void findType(ArrayList list) {
        System.out.println(Arrays.toString(
                list.getClass().getTypeParameters()));
    }

    public static void main(String[] args) {
        findType(new ArrayList<Integer>());
        findType(new ArrayList<String>());
    }
}

Based on natural instinct, we expect the output to be:

[Integer]
[String]

Instead, we get the identifiers that are used as the parameter placeholders.

[E]
[E]

So in Java, you don't know the actual type parameter(s) used to create a particular instance of ArrayList. This is because Java generics are implemented using erasure.

This means the specific type information is erased from a generic. The only thing you know for sure is that you are using an object.

This is quite different from C++'s template world.

There are a few more differences but I will not get in here.

Indra Basak
  • 7,124
  • 1
  • 26
  • 45
  • Thanks. In `public static void findType(ArrayList list) `, don't you have to specify type parameter i.e. `public static void findType(ArrayList list) `? – Tim Sep 18 '17 at 03:19
  • No, you never specify `T` when you are using a generic class. `T` (or any other letter or word) is the type parameter used during type definition. Instead, you can use `?`(wildcard) or a concrete type, e.g., `public static void findType(ArrayList> list) `. In my example, I didn't. If I have used it, the result would have been the same. – Indra Basak Sep 18 '17 at 03:23
  • Thanks. Is `ArrayList list` in `public static void findType(ArrayList list)` the same as an instantiation `ArrayList list`? – Tim Sep 20 '17 at 21:08
  • It's same as `ArrayList> list`. It will accept `java.lang.Object` but you can't declare it as `ArrayList`. – Indra Basak Sep 20 '17 at 21:13
  • Thanks. Why I can't declare it as `ArrayList`? Is `Object` not a concrete type? Is `ArrayList>` an instantiation of generic `ArrayList` with some type argument? – Tim Sep 20 '17 at 22:15
  • Here is a good explanation (here)[https://docs.oracle.com/javase/tutorial/extra/generics/subtype.html]. – Indra Basak Sep 20 '17 at 22:32