Java Generics - raw type and parameterized type conversion

I read Java Generics tutorials and a few threads in Stackoverflow that deal with Generics, and still could not figure out a specific case. There he is:

public class Box<T>
{
    private T t;

    public T getT ()
    {
        return t;
    }

    public void setT (T t)
    {
        this.t = t;
    }

    public static void main (String[] args)
    {
        Box<Integer> intBox = new Box<Integer>();
        Box rawBox = intBox;
        rawBox.setT("NBA");
        System.out.println(rawBox.getT());
        System.out.println(intBox.getT());
        /*1*/ //System.out.println(intBox.getT().toString());
    }
}

Here is the deal, the first seal that I understand, that is

 System.out.println(rawBox.getT());

prints NBA because rawBox has a raw Box T type and it "gives" us objects.

What I am not getting is the second print:

System.out.println(intBox.getT());

NBA. intBox ( Box of Integer), , getter T ( Integer), , String, , Integer ( , Box T), ClassCastException , , ?

, /1/ , , , , ClassCastException (String Integer), ,

:)

+4
3

, Java . , , . , , - -!

javap -c Box.class ( /*1*/ ), :

  public static void main(java.lang.String[]);
    Code:
      ...
      20: invokevirtual #8                  // Method getT:()Ljava/lang/Object;
      23: invokevirtual #9                  // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      26: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;
      29: aload_1
      30: invokevirtual #8                  // Method getT:()Ljava/lang/Object;
      33: invokevirtual #9                  // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
      36: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;
      39: aload_1
      40: invokevirtual #8                  // Method getT:()Ljava/lang/Object;
      43: checkcast     #10                 // class java/lang/Integer
      46: invokevirtual #11                 // Method java/lang/Integer.toString:()Ljava/lang/String;
      49: invokevirtual #12                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      52: return

, , JVM , # 43 (checkcast). , invokevirtual Integer.toString().

println (# 33) , println Object, Integer (, , println(int), ), JVM , , .

println(Object) , Integer, ClassCastException.

, :

    ...
    print(intBox.getT());
}

private static void print(Integer integer) {
    System.out.println(integer);
}

:

  26: aload_1
  27: invokevirtual #8                  // Method getT:()Ljava/lang/Object;
  30: checkcast     #10                 // class java/lang/Integer
  33: invokestatic  #11                 // Method print:(Ljava/lang/Integer;)V
+2

. Box , . , , .

+1

This is why the compiler warns you about using non-generic class references. At runtime, it cannot know what type of intbox exists, because it is not stored in bytecode.

0
source

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


All Articles