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 instrlasterror
overridingseterror()
inlasterror
class. however, not case. @ time of compilation, knowledge of types
not 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 infert
string
because 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