Appropriate use of Java generics on collection -
i've never had chance play generics before (as in writing classes generics), need arises, , i've come across confusion.
there's interface, meant wrapper of something. implementations not collections, so, every instance has access 1 something.
public interface resource<t> { // expected operations: void write(resourcestate state); resourcestate read(); }
as implementations, expect have exclusiveresource<t>
, , shareableresource<t>
, differ mainly/only in locking scheme used (regular lock, , read-write lock, respectively).
how read
, write
performed, i'm planning on using strategy pattern.
instance, might have
// implement strategy<file>. filestrategy fs = new filestrategy(); resource<file> r = new exclusiveresource<file>(fs);
now, i've got sort of collection of these resources, say, resource pool.
i'd map key each resource, in resource pool, , i'd add, retrieve , remove resources, i'm not sure how declare map , methods. i've tried following:
public class resourcepool { // instance variables private final map<string, resource<?>> map; /** empty constructor of objects of class resourcepool. */ public resourcepool() { map = new hashmap<string, resource<?>>(); } /** */ public resource<?> get(string s) { return map.get(s); } /** */ public void add(string s, resource<?> r) { map.put(s, r); } // ... }
this not seem appropriate way it, and, quoting josh bloch, on effective java reloaded:
user should not have think wildcards use api.
i've tested code following method:
public static void test() { resourcepool rp = new resourcepool(); resource<string> r1 = new shareableresource<>("test"); resource<integer> r2 = new shareableresource<>(1); resource<list<string>> r3 = new shareableresource<>( arrays.aslist(new string[]{"1", "2"}) ); // these ok. rp.add("1", r1); rp.add("2", r2); rp.add("3", r3); // results in compiler error (incompatible types). resource<string> g1 = rp.get("1"); // results in compiler warning (unsafe operation). resource<string> g2 = (resource<string>) rp.get("1"); }
i don't it, when code compiles warnings. makes me feel guilty, , seems hint @ bad coding.
so, question how should handle situation.
is right way i'm trying do?
can done in such way there no unsafe operations?
i don't think there's way avoid unchecked casts using design. said, can avoid having cast every time retrieve resource
:
@suppresswarnings("unchecked") public <t> resource<t> get(string s, class<t> c) { return (resource<t>) map.get(s); }
when want retrieve resource
, pass in desired class, so:
resource<string> g1 = rp.get("1", string.class);
you should careful design, though, since there no runtime guarantee returned resource
resource<string>
.
Comments
Post a Comment