Java Generics: Is any generic type meta information stored at runtime?

Background

My understanding of Java generics is a complete compile-time function (mainly focusing on type safety checks). Type information for any generic class is lost at runtime (type deletion).

However, I see that many frameworks seem to use type information at runtime. For example, google guice Providers . The guice provider can instantiate and provide new instances of this type at runtime.

class Container { @Inject public Container(Provider<Content> contentProvider) { //This works at Runtime... but How ??? //When type are not even preserved at runtime, how does the Provider knows it has to instantiate an object of type 'Content' Content content = contentProvider.get(); } } 

Question

  • Is there any information related to the generic types that is stored at runtime.? If so , what ?. If not , than libraries like google guice work inside (above)

  • Is there more to generics than just compile-time security? As in the case, is there any precedent (other than ensuring compile-time security) where you could take advantage of generics?

+1
source share
6 answers

Of course, information that the class is shared is supported.

In other words: when you decompile ArrayList.class, you will find hints that this class allows one common type parameter. In other words: class files contain meta information. And using reflection, you can check this meta information at runtime.

But if you have another class that uses some List<Integer> object, then you will not find information that "list uses Integer" in the compiled class - unless you use some specific templates, as indicated here .

Thus, the answer is mainly: for almost all cases of practical significance of "generics" - this is compilation time.

Example:

 public class GenericsExample<T> { private T member; public T foo(T bar) { return member; } } 

Now run: javap -p -c GenericsExample

 Compiled from "GenericsExample.java" public class GenericsExample<T> { private T member; public GenericsExample(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return public T foo(T); Code: 0: aload_0 1: getfield #2 // Field member:Ljava/lang/Object; 4: areturn } 

As you can see, the decompiler understands that the class uses this generic type T. For more details see here or there .

+2
source

If a class extends a common class or interface and provides a specific type for a parameter, then this type is available through Class.getGenericSuperclass() . This method (in this case) will return a ParameterizedType that will contain the actual parameterization.

For example, if you have:

 class BigIntegerList extends ArrayList<BigInteger> {} 

Then you can do:

 Class<BigIntegerList> fooClass = BigIntegerList.class; Type superclass = fooClass.getGenericSuperclass(); if (superclass instanceof ParameterizedType) { ParameterizedType parameterized = (ParameterizedType) superclass; Type[] parameterizations = parameterized.getActualTypeArguments(); System.out.println(Arrays.toString(parameterizations)); // prints: "[class java.math.BigInteger]" } 

It is really used by abstract-heavy libraries such as Guice. Another example is the Jackson TypeReference , which can allow you to read the JSON list as a BigDecimal list (for example).

+2
source

Generics is a good way to program if you don't know what type you are going to use for a particular class. At run time, the type of the generic class will be set based on the input of the class. This is mainly useful for ensuring compile-time security.

0
source
  • Java Generics uses something like type erasure, so no type information is available at runtime. However, you can instantiate any class using the Class.newInstance() method if the type information can be passed in somehow (in fact, this is the only way to create a shared array)

  • Compile-time security is the main goal of generics. But they can often be used to write more concise code, which would be impossible otherwise

For detailed treatment, I recommend the excellent Java Generics and Collections book.

0
source

Is there any information regarding common types that are stored at runtime.? If yes, then what ?.

The single information stored in the compiled class represents the drawing from the raw objects / variables obtained after erasing to specific types that are used as common in the source code.
But they rely only on the declared type of the variable, and not on the regular generic type.

Thus, at run time, you cannot directly access general information without a workaround as a class transfer when instantiating a generic class.

If not, how do libraries like google guice work inside (

You are wrong.
In Guice, this code:

  Content content = contentProvider.get(); 

will return an instance of Content , not a generic type. See the documentation :

T get ()

Provides an instance of T.

0
source

General information is saved only until compilation. In your example, it is also available until compilation. Let me explain it with one example.

Public void printObject (list empt) {

// This does not show that this list stores this information at runtime, what type of object it will return. Occupation en = empt.get (); }

-2
source

Source: https://habr.com/ru/post/1271405/


All Articles