java - difference behaviour for generic method within generic class and for generic method within non-generic class -


i investigate generic behaviour

i noticed that:

public class hohol1 {     public class my<t> {         public <e> void test(collection<e> es) { system.out.println("collection<e>");         }          public void test(list<integer> integerlist) {             system.out.println("list<integer>");             (integer integer : integerlist) {                 system.out.println(integer);             }         }     }      public static void main(string[] args) {         my1 = new hohol1().new my();         my1.test(new arraylist<string>() { {add("1");} });     } } 

code above returns

exception in thread "main" java.lang.classcastexception: java.lang.string cannot cast java.lang.integer     @ genericstest.hohol1$my.test(hohol1.java:22)     @ genericstest.hohol1.main(hohol1.java:31)     @ sun.reflect.nativemethodaccessorimpl.invoke0(native method)     @ sun.reflect.nativemethodaccessorimpl.invoke(nativemethodaccessorimpl.java:57)     @ sun.reflect.delegatingmethodaccessorimpl.invoke(delegatingmethodaccessorimpl.java:43)     @ java.lang.reflect.method.invoke(method.java:606)     @ com.intellij.rt.execution.application.appmain.main(appmain.java:120) 

but if make my non-generic so

  public class hohol1 {         public class my/*deleted generic type t*/ {              ....         }      } 

this code returns collection<e>

it surpised behaviour me , don't understand why created so.

what think it?

p.s. use double brace initialization laconic

first, when using raw form of inner class my, in class, including unrelated specified type parameters such method parameter list<integer> integerlist act if own type erasure in place, e.g. list integerlist.

however, pass in anonymous subclass of arraylist (effectively arraylist) of strings. specific method applies test(list<integer> integerlist), because it's viewed list, arraylist is. still runs until enhanced for loop attempts print integers, can't convert string such "1" integer, classcastexception.

but if make my non-generic, type of parameter integerlist not erased. compiler can see list<integer> doesn't match, collection<e> match, test(collection<e> es) matches , "collection<e>" printed.

the reason specified in jls, section 4.8:

more precisely, raw type defined 1 of:

  • the reference type formed taking name of generic type declaration without accompanying type argument list.

...

and

the type of constructor (§8.8), instance method (§8.4, §9.4), or non-static field (§8.3) m of raw type c not inherited superclasses or superinterfaces raw type corresponds erasure of type in generic declaration corresponding c.

the reasoning given:

the use of raw types allowed concession compatibility of legacy code. use of raw types in code written after introduction of generics java programming language discouraged. possible future versions of java programming language disallow use of raw types.


Comments

Popular posts from this blog

php - SPIP: From Tag directly to an article -

jquery - isAjaxRequest always return false -

ruby on rails - In a controller spec, how to find a specific tag in the generated view? -