java - Why this converter needs casting? -
i need implement enum enum converter in java: enum_2
> enum_1
, i'd in generic way.
so defined interface:
interface labelaware<t extends enum> { string getlabel(); t getobject(); }
and enum_1
:
enum enum_1 { a, b; string getvalue() { return "whatever"; } }
and enum_2
implements labelaware
, need converted enum_1
:
enum enum_2 implements labelaware<enum_1> { c("c", enum_1.a), d("d", enum_1.b); private final string label; private final enum_1 object; enum_2(string label, enum_1 object) { this.label = label; this.object = object; } public string getlabel() { return label; } public enum_1 getobject() { return object; } }
finally, here's generic converter (list.ofall()
comes javaslang):
class converter<s extends labelaware, d extends enum> { private s[] values; converter(s[] values) { this.values = values; } d map(string label) { return (d) list.of(values) .find(v -> v.getlabel().equals(label)) .map(labelaware::getobject) .getorelsethrow(() -> new runtimeexception("")); } }
and main method:
public class main { public static void main(string[] args) { system.out.println(new converter<enum_2, enum_1>(enum_2.values()).map("c").getvalue()); } }
it compiles , runs well, i've no ides why need cast result of converter.map
method d
, since i've declared d
extend enum
. can done in generic way without warnings?
as general rule, warnings related generics should handled have safer code , avoid warning chain (the visible warning caused far warning of dependency chain).
but in case, have not warning chain problem since externally, labelaware
safe.
labelaware
has internal warning (in implementation) enum
in extends enum
raw-declared.
here, single missing generic declaration explains why cast in converter.map()
method not safe : converter
class declaration doesn't specify generic labelaware
.
you declare converter
class :
class converter<s extends labelaware, d extends enum> {
with value
field of type s
:
private s[] values;
and map()
method :
d map(string label) { return (d) list.of(values) .find(v -> v.getlabel().equals(label)) .map(labelaware::getobject) .getorelsethrow(() -> new runtimeexception("")); }
in map()
, here .find(v -> v.getlabel().equals(label))
, retrieve s
instance , declared s extends labelaware
. therefore finally, retrieve instance of labelaware
or extending it.
and labelaware
typed enum
generic :
interface labelaware<t extends enum> { string getlabel(); t getobject(); }
so, in map()
method when .map(labelaware::getobject)
called, retrieve enum
type .
and enum
type not d
type, while reverse true.
therefore, if want avoid cast (and related warning) in map()
, should specify generic type returned getobject()
instance of d
typing labelaware
d
generic :
class converter<s extends labelaware<d>, d extends enum> {
Comments
Post a Comment