3

Is it right that this code

List<Integer> test2 = new ArrayList<Integer>();
test2.add(343);
int x2 = test2.get(0);

in compile time will be converted to this

List test = new ArrayList();
test.add(343);
int x = (Integer)test.get(0);

Something similar with autoboxing...

4 Answers 4

3

Yes, except that "test2.add(343);" will not change to "test.add(43);"

Sign up to request clarification or add additional context in comments.

1 Comment

i copied it from scjp book, so it is matter to right them that their code is a little bit confused :)
2

Let's try. Take this class with two methods that do absolutely the same thing with and without generics and autoboxing:

public class GenericTest{

    // use generics and auto-boxing
    // Java 1.5 or higher required
    public void generic(){
        final List<Integer> test2 = new ArrayList<Integer>();
        test2.add(343);
        final int x2 = test2.get(0);
    }

    // use neither generics nor auto-boxing,
    // this should be Java 1.4-compatible
    public void nonGeneric(){
        final List test2 = new ArrayList();
        test2.add(Integer.valueOf(343));
        final int x2 = ((Integer) test2.get(0)).intValue();
    }
}

Here's the byte code:

// Compiled from GenericTest.java (version 1.6 : 50.0, super bit)
public class GenericTest {

  // Method descriptor #6 ()V
  // Stack: 1, Locals: 1
  public GenericTest();
    0  aload_0 [this]
    1  invokespecial java.lang.Object() [8]
    4  return
      Line numbers:
        [pc: 0, line: 4]
      Local variable table:
        [pc: 0, pc: 5] local: this index: 0 type: GenericTest

  // Method descriptor #6 ()V
  // Stack: 2, Locals: 3
  public void generic();
     0  new java.util.ArrayList [16]
     3  dup
     4  invokespecial java.util.ArrayList() [18]
     7  astore_1 [test2]
     8  aload_1 [test2]
     9  sipush 343
    12  invokestatic java.lang.Integer.valueOf(int) : java.lang.Integer [19]
    15  invokeinterface java.util.List.add(java.lang.Object) : boolean [25] [nargs: 2]
    20  pop
    21  aload_1 [test2]
    22  iconst_0
    23  invokeinterface java.util.List.get(int) : java.lang.Object [31] [nargs: 2]
    28  checkcast java.lang.Integer [20]
    31  invokevirtual java.lang.Integer.intValue() : int [35]
    34  istore_2 [x2]
    35  return
      Line numbers:
        [pc: 0, line: 7]
        [pc: 8, line: 8]
        [pc: 21, line: 9]
        [pc: 35, line: 10]
      Local variable table:
        [pc: 0, pc: 36] local: this index: 0 type: GenericTest
        [pc: 8, pc: 36] local: test2 index: 1 type: java.util.List
        [pc: 35, pc: 36] local: x2 index: 2 type: int
      Local variable type table:
        [pc: 8, pc: 36] local: test2 index: 1 type: java.util.List<java.lang.Integer>

  // Method descriptor #6 ()V
  // Stack: 2, Locals: 3
  public void nonGeneric();
     0  new java.util.ArrayList [16]
     3  dup
     4  invokespecial java.util.ArrayList() [18]
     7  astore_1 [test2]
     8  aload_1 [test2]
     9  sipush 343
    12  invokestatic java.lang.Integer.valueOf(int) : java.lang.Integer [19]
    15  invokeinterface java.util.List.add(java.lang.Object) : boolean [25] [nargs: 2]
    20  pop
    21  aload_1 [test2]
    22  iconst_0
    23  invokeinterface java.util.List.get(int) : java.lang.Object [31] [nargs: 2]
    28  checkcast java.lang.Integer [20]
    31  invokevirtual java.lang.Integer.intValue() : int [35]
    34  istore_2 [x2]
    35  return
      Line numbers:
        [pc: 0, line: 13]
        [pc: 8, line: 14]
        [pc: 21, line: 15]
        [pc: 35, line: 16]
      Local variable table:
        [pc: 0, pc: 36] local: this index: 0 type: GenericTest
        [pc: 8, pc: 36] local: test2 index: 1 type: java.util.List
        [pc: 35, pc: 36] local: x2 index: 2 type: int
}

I don't see any obvious difference between the generic and the non-generic version, in fact here's the diff result for the two methods:

<  public void generic();
---
>   public void nonGeneric();
19,22c19,22
<         [pc: 0, line: 7]
<         [pc: 8, line: 8]
<         [pc: 21, line: 9]
<         [pc: 35, line: 10]
---
>         [pc: 0, line: 13]
>         [pc: 8, line: 14]
>         [pc: 21, line: 15]
>         [pc: 35, line: 16]
27,28d26
<       Local variable type table:
<         [pc: 8, pc: 36] local: test2 index: 1 type: java.util.List<java.lang.Integer>

As you can see, the only difference is in the line numbers and the local variable table.

2 Comments

Would it make a difference if this was compiled with a 1.4 compiler?
@glowcoder the first method wouldn't compile with a 1.4 compiler, and the second would be identical, that's the whole point of this type erasure crap.
1

Yes.

[[Mandatory filler to achieve > 30 chars]]

Comments

1

Yes:

List test = new ArrayList();
test.add(Integer.valueOf(343));
int x = ((Integer) test.get(0)).intValue();

1 Comment

Thanks, forgot about autoboxing

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.