I have a generic Container which holds objects of type E:
public class Container<E> {
private final E e;
public Container(E e) {
this.e = e;
}
public E get() {
return e;
}
}
I have a bucket which holds various containers:
public class Bucket {
private final Map<String, Container<?>> containers = new HashMap<>();
public void put(String name, Container<?> container) {
containers.put(name, container);
}
public Container<?> get(String name) {
Container<?> container = containers.get(name);
return container;
}
}
I want to be able to put containers (of various types) into the bucket and retrieve them back in a type-safe way.
Container<Long> longs = new Container<>(100L);
Container<String> strings = new Container<>("Hello");
Bucket bucket = new Bucket();
bucket.put("longs", longs);
bucket.put("strings", strings);
But as you can I lost type-safety:
Container<?> longs1 = bucket.get("longs");
Container<?> strings1 = bucket.get("strings");
I can't seem to figure out what it'd take that would allow me achieve the following:
Container<Long> longs1 = bucket.get("longs");
Container<String> strings1 = bucket.get("strings");
My solution. I guess it serves my need pretty good:
public class Container<E> {
private final E e;
public Container(E e) {
this.e = e;
}
public <T> T get(Class<T> target) {
if (target.isAssignableFrom(e.getClass())) {
return (T) e;
}
throw new ClassCastException(e.getClass().getName() + " '" + e + "' cannot be converted to " + target.getName());
}
}
public class Bucket {
private final Map<String, Container<?>> containers = new HashMap<>();
public void put(String name, Container<?> container) {
containers.put(name, container);
}
public Container<?> getContainer(String name) {
return containers.get(name);
}
}
Putting it to test:
Container<Long> longs = new Container<>(100L);
Container<String> strings = new Container<>("Hello");
Bucket bucket = new Bucket();
bucket.put("longs", longs);
bucket.put("strings", strings);
Container<?> longContainer = bucket.getContainer("longs");
Long aLong = longContainer.get(Long.class);
log.debug("{}", aLong); // Prints 100
Container<?> stringContainer = bucket.getContainer("strings");
String aString = stringContainer.get(String.class);
log.debug("{}", aString); // Prints Hello
log.debug("{}", stringContainer.get(Long.class)); // Throws java.lang.ClassCastException: java.lang.String 'Hello' cannot be converted to java.lang.Long
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.