generics - java type inference in builder pattern -
i want create parameterized (generic) class mytype<t>
, builder. builder have methods ignore type t
, methods use type. seems using pattern have repeat t
declaration:
how omit declaration? | v mytype<string> mytype = builder.<string>of() .method1(argument_can_be_of_any_type) .method2(argument_must_be_of_type_t = string) .build();
is possible use java syntax tricks or other design patterns omit second type declaration , make api more user friendly? example:
list<string> alist = lists.emptylist();
or
list<string> alist = new linkedlist<>();
i don't want enforce order of methods in builder
i've reworked things bit since original answer didn't work advertised. (thanks shmosel spotting problem, , daniel pryden suggested solution.)
/* contents of box.java */ public class box<t> { private t contents; private object data; protected box(t contents, object data) { this.contents = contents; this.data = data; } public static boxbuilder builder() { return new boxbuilder(); } public t getcontents() { return contents; } } /* contents of boxbuilder.java */ public class boxbuilder { private object data; public boxbuilder withanything(object o) { this.data = o; return this; } // infers new type argument public <t> typedboxbuilder<t> withboxcontent(t contents) { typedboxbuilder<t> builder = new typedboxbuilder<t>(); builder.setdata(data); builder.setcontents(contents); return builder; } } /* contents of typedboxbuilder.java */ public class typedboxbuilder<t> { private t contents; private object data; public typedboxbuilder() { } public typedboxbuilder<t> withanything(object data) { this.data = data; return this; } public typedboxbuilder<t> withcontents(t contents) { this.contents = contents; return this; } public box<t> build() { return new box<t>(contents, data); } public void setcontents(t contents) { this.contents = contents; } public void setdata(object data) { this.data = data; } }
and here's client code:
box<string> box = box.builder() // returns boxbuilder .withboxcontent("foo") // returns typedboxbuilder<string> .withanything(42) // returns typedboxbuilder<string> .build(); // returns box<string> string c = box.getcontents();
and works well:
box<string> box = box.builder() // returns boxbuilder .withanything(42) // returns boxbuilder .withboxcontent("foo") // returns typedboxbuilder<string> .build(); // returns box<string> string c = box.getcontents();
Comments
Post a Comment