Unable to choose appropriate method using Java Generics -


this program doesn't wanted. prints "sad" twice, whereas hoping print "happy" , "sad".

public class woof {      public static class arf<t> {         t yap;         public arf(t yap) {             this.yap = yap;         }          public string woof() {             /*              * should select doyapstuff() based on whether t              * happens integer, or else.              */             return doyapstuff(yap);         }          /* special case implementation of doyapstuff() t integer */         public string doyapstuff(integer x) {             return "happy";         }          /* default implementation of doyapstuff() t else */         public string doyapstuff(t x) {             return "sad";         }     }      public static void main(string[] args) {         integer = 5;         arf<integer> arf1 = new arf<integer>(i);         system.out.println(arf1.woof()); // should print "happy"          string s = "foo";         arf<string> arf2 = new arf<string>(s);         system.out.println(arf2.woof()); // should print "sad"     }  } 

this explained in blog: http://www.angelikalanger.com/genericsfaq/faqsections/programmingidioms.html#faq050

relevant quote:

how can happen? pass argument of type string overloaded method , yet version type object called. reason compiler creates 1 byte code representation per generic type or method , maps instantiations of generic type or method 1 representation.

in our example generic method translated following representation:

(edit: changed method match question)

public string doyapstuff(object x) {             return "sad"; } 

considering translation, should obvious why object version of overloaded method invoked. entirely irrelevant type of object passed generic method , passed along overloaded method. observe call of object version of overloaded method.

more speaking: overload resolution happens @ compile time, is, compiler decides overloaded version must called. compiler when generic method translated unique byte code representation. during translation type erasure performed, means type parameters replaced leftmost bound or object if no bound specified. consequently, leftmost bound or object determines version of overloaded method invoked. type of object passed method @ runtime entirely irrelevant overload resolution.

you can see if @ compiled bytecode:

 4  getfield woof$arf.yap : java.lang.object [16]  7  invokevirtual java.io.printstream.println(java.lang.object) : void [32] 10  aload_0 [this] 11  aload_0 [this] 12  getfield woof$arf.yap : java.lang.object [16] 15  invokevirtual woof$arf.doyapstuff(java.lang.object) : java.lang.string [37] 18  areturn 

to achieve want, should use strategy pattern.

public interface yapsound{      string     doyapsound(); }  public class happysound implements yapsound{      @override     public string doyapsound() {           return "happy";      }  }  public class sadsound implements yapsound{      @override     public string doyapsound() {         return "sad";     }  }  public class arf {     yapsound yap;     public arf(yapsound yap) {         this.yap = yap;     }      public string woof() {         /*          * should select doyapstuff() based on whether t          * happens integer, or else.          */         return yap.doyapsound();     }   }  public static void main(string[] args) {      arf arf1 = new arf(new happysound());     system.out.println(arf1.woof()); // should print "happy"      arf arf2 = new arf(new sadsound());     system.out.println(arf2.woof()); // should print "sad" } 

Comments

Popular posts from this blog

python - mat is not a numerical tuple : openCV error -

c# - MSAA finds controls UI Automation doesn't -

wordpress - .htaccess: RewriteRule: bad flag delimiters -