Java: raw types versus generics

Consider the sample code below

/* The new Java 5 or later Generic code */
class TestInserter {
    public static void main(String[] ar) {
        List<Integer> myList = new ArrayList<Integer>();
        myList.add(20);
        myList.add(42);
        Inserter ins = new Inserter();
        ins.insert(myList);
    }
}

/* Legacy Code */
class Inserter {
    public void insert(List list) {
        list.add(new Integer(55));
    }
}

Compiling and executing the above code will perform just fine, without any complaints from the compiler or JVM. The non type-safeinsert () method inserts a new Integer object into our type-safeArrayList. However, if I changed the insertion method to something like this:

public void insert(List list) {
        list.add(new String("55"));
}

What are they saying ?! will the above code work? Think about it, yes, of course, it will work, it is strange, but yes, this code compiles and works just fine. This is slightly different from arrays, which gives you both compile time and runtime protection and prevents such things. Why did they work this way? Why does Java allow Generics to enter a value other than the specified one?

+4
2

. insert Integer , , myList. String ArrayList, Integer, , , Integer - String.

, , - JVM , String ArrayList, Integer s. . , erasure, . , - :

List<Integer> myList = new ArrayList<>();

:

List myList = new ArrayList();

?

! , Java , Million Java Trillions Java, !

; :

$> javac TestInserter.java  
Note: TestInserter.java uses unchecked or unsafe operations.  
Note: Recompile with -Xlint:unchecked for details.

, :

$> javac -Xlint:unchecked TestInserter.java
TestInserter.java:15: warning: [unchecked] unchecked call to add(E) as a member of the raw type List  
        list.add(new String("55"));  
                 ^  
where E is a type-variable:  
  E extends Object declared in interface List  
1 warning    

, , , - .

, , . (, ), , ( ) . - ! .

+3

, . , , (RTTT), Class<T>, T .

public class Foo<T> {
  private final Class<T> rttt;
  public Foo(Class<T> rttt) {
    if (rttt == null) {
      throw new IllegalArgumentException("null rttt");
    }
    this.rttt = rttt;
  }
  // etc. RTTT handles runtime type safety
}

, , Java , . ( "reifiable" ) . - .

, , . . . .

+1

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


All Articles