Java Generics, Type Inference, Inheritance? -
i'm reading type inference generics, , code provided example fails compile.
import java.io.*; class lasterror<t> { private t lasterror; void seterror(t t){ lasterror = t; system.out.println("lasterror: seterror"); } } class strlasterror<s extends charsequence> extends lasterror<string>{ public strlasterror(s s) { } void seterror(s s){ system.out.println("strlasterror: seterror"); } } class test { public static void main(string []args) { strlasterror<string> err = new strlasterror<string>("error"); err.seterror("last error"); } } and explanation given in book was:
"(it looks
seterror()method instrlasterroroverridingseterror()inlasterrorclass. however, not case. @ time of compilation, knowledge of typesnot available. therefore, compiler records signatures of these 2 methodsseterror(string)in superclass ,seterror(s_extends_charsequence)in subclass—treating them overloaded methods (not overridden). in case, when callseterror()found, compiler finds both overloaded methods matching, resulting in ambiguous method call error."
i don't understand why type s can't inferred @ compile time. string passed when invoking constructor of class strlasterror, , api docs, string implement interface charsequence, doesn't mean s <s extends charsequence> of type string?
i've read java online tutorial on topic of generics several times. i've checked "type inference", , inheritance, don't know how whole thing works. need explanation on question.
the points i'm stuck @ are:
- if subtype can't decide
s, how come super type can decidet, because superclass not have upper bound? or infertstringbecause subtype calls supertype's constructor first? i understand if constructor invoked as:
strlasterror<charsequence> err = newstrlasterror<>((charsequence)"error");there no ambiguity, since it's plain method overriding then. (or wrong here?)
however, said in beginning, if string passed, why can't s inferred string?
if subtype can't decide s, how come super type can decide t, because superclass not have upper bound? or infer t string because subtype calls supertype's constructor first?
the super type isn't deciding or inferring t is; you're explicitly telling t declaration:
class strlasterror<s extends charsequence> extends lasterror<string> t bound string lasterror, makes every reference t in parent class concrete string.
your child class has bound s extends charsequence attached it, independent bounds applied parent class.
what happens java compile child class, , result of child class 2 methods signature matches string created. (key note here: a string is-a charsequence.)
in child class, seterror(ljava/lang/charsequence;)v generated signature seterror. because of way generics work, lasterror#seterror treated if has signature of seterror(ljava/lang/string;)v. why when go override method, place string type parameter instead of else.
so, arrive @ two methods have override-equivalent signatures.
void seterror(charsequence s) void seterror(string s) jls 8.4.8.4. applies here.
it possible class inherit multiple methods override-equivalent signatures (§8.4.2).
it compile-time error if class c inherits concrete method signature subsignature of concrete method inherited c. can happen if superclass generic, , has 2 methods distinct in generic declaration, have same signature in particular invocation used.
i understand if constructor invoked strlasterror err = new strlasterror<>((charsequence)"error"); there no ambiguity, since plain method overriding then.(or i'm wrong here)
no, you're messing raw types. interestingly enough work, because signatures 2 methods has become:
void seterror(object s) void seterror(string s) you want use generics avoid scenario this; may want invoke super class method @ point, in scenario these bindings, it's difficult accomplish.
Comments
Post a Comment