Java Typesafe Heterogeneous Container Example

In this example of a Map, unlike other examples, a String key, not a class type, is used as the selector.

Thought I’d try it after reading about how to implement “Typesafe Heterogeneous Container Pattern” using Generics.

“Typesafe” here refers to compile time safety. Can you can still get ClassCastException when accessing elements during run-time when the put method is also typesafe?

Created the simplest example. In this example, a Map is created and the key is used to access the stored data.

In the original presentation and many examples on the web, the class type of the stored item is used to locate the item. I don’t understand the utility of that. Then how would you store two items of the same class type? Create new types just for storage into a type-safe collector? Seems overly complex. Instead, in the example below, I get(key, type).

Listing one

import java.util.HashMap;
import java.util.Map;

/**
 * @author jbetancourt
 * @see <a href="http://developers.sun.com/learning/javaoneonline/sessions/2009/pdf/TS-5217.pdf">
 * Effective Java:  Still Effective, After All These Years</a>
 * @see <a href="http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf">generics-tutorial.pdf</a>
 */
public class TypesafeHeterogeneousContainerExample {
	/** COLLECTION */
	public static Map<String, Object>  stuff = 
        new HashMap<String, Object>();
	
	/** PUT */
	public static <T> void put(String key, 
            Class<T>type, T instance){
		stuff.put(key, instance);		
	}
	
	/** GET */
	public static <T> T get(String key, Class<T>type){
		return type.cast(stuff.get(key));
	}	
	
	/** TEST */
	public static void main(String[] args) {
		put("greeting",String.class, "Hello world!");
		
		String s = get("greeting", String.class);
	
		// works 
		assert (s.compareTo("Hello world!") == 0);
		
		// this line won't compile:
		// put("num", String.class, new Long(123));	
		
		// this won't compile of course:
		// put("Doh!");

		// this won't compile
		// Date date = get("greeting", String.class);
		
		try {
			// throws exception ...
			get("greeting", Long.class);
		} catch (ClassCastException e) {
			// e.printStackTrace();
		}
		
	}

}

Yes, I know that the ‘static’ usage above is incorrect. This is just a “Hello world!” example.

Addedum

There seems to be a misuse of class types for programming. As another example, in the article “ServiceLoader and how it relates to OSGi“, the author discusses how locating a service via it’s interface is a bad idea. I wonder if this may point to an existing AntiPattern.

Further Reading

Similar Posts:

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

Leave a Reply

Your email address will not be published. Required fields are marked *