When do java generics use transformations at run time?

I'm reading a discussion about C templates and c# generics and how they differ from Java type erasure generics I read a statement that Java still uses transformations at runtime, such as when dealing with collections If this is true, I don't know it!

Suppose I have the following code:

ArrayList<SomeClass> list = new ArrayList<SomeClass>();
...
SomeClass object = list.get(0);

My problem is Is this a valid compilation

ArrayList list = new ArrayList();
...
SomeClass object = (SomeClass) list.get(0);

If so, why? I think the type of list is ArrayList < < someclass >, which ensures that only someclass is stored in ArrayList at compile time and runtime? Or can you do unsafe type conversion to convert ArrayList < otherclass > to ArrayList < someclass >?

Are there other occasions for runtime type conversion in Java generics?

Finally, if you do use a run-time transformation, can the JIT ignore the run-time transformation check?

(please don't answer / comment that micro optimization is not worth it. Preemptive optimization is the source of all evil, etc. I have seen these on other similar questions. These points are well understood, but they don't take away trying points to understand how to implement type erasure generics under the hood.)

Solution

This is a short program I wrote:

public class Test<T> {

  public T contents;

  public Test(T item) {
    contents = item;
  }

  public static void main(String[] args) {

    Test<String> t = new Test<String>("hello");
    System.out.println(t.contents);

  }

}

Try to compile it in javac, and then use javap - verbose to view the bytecode I chose several interesting lines:

public java.lang.Object contents;

This should occur before the definition of the test constructor In the sample code, it is type T, and now it is an object This is erasure

Now let's look at the main methods:

public static void main(java.lang.String[]);
Code:
   Stack=3,Locals=2,Args_size=1
   0:   new #3; //class Test
   3:   dup
   4:   ldc #4; //String hello
   6:   invokespecial   #5; //Method "<init>":(Ljava/lang/Object;)V
   9:   astore_1
   10:  getstatic   #6; //Field java/lang/System.out:Ljava/io/PrintStream;
   13:  aload_1
   14:  getfield    #2; //Field contents:Ljava/lang/Object;
   17:  checkcast   #7; //class java/lang/String
   20:  invokevirtual   #8; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   23:  return

Then we can see the checkcast command on line 17, just before println - this is the string that Java converts from object to erased generic type - string

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>