title: Cast a raw map to a generic map using a method, cleanly and safely in a fail early manner
body: <p><a href="https://stackoverflow.com/questions/509076/how-do-i-address-unchecked-cast-warnings">Casting</a>, <a href="http://blog.joda.org/2007/01/java-language-dynamic-instanceof_7967.html" rel="nofollow noreferrer">instanceof</a>, and <a href="https://stackoverflow.com/questions/1129795/what-is-suppresswarnings-unchecked-in-java">@SuppressWarnings("unchecked")</a> are noisy.  It would be nice to stuff them down into a method where they won't need to be looked at.  <code>CheckedCast.castToMapOf()</code> is an attempt to do that.</p>
  
  <p><code>castToMapOf()</code> is making some assumptions:</p>
  
  <ul>
  <li>(1) The map can't be trusted to be <a href="http://voyager.deanza.edu/~hso/cis35a/lecture/java11/collection/homo.html" rel="nofollow noreferrer">homogeneous</a></li>
  <li>(2) Redesigning to <a href="https://stackoverflow.com/questions/6157835/avoiding-instanceof-in-java?rq=1">avoid need for casting or instanceof</a> is not viable</li>
  <li>(3) Ensuring type safety in an <a href="http://www.leepoint.net/notes-java/principles_and_practices/40fail-early-fail-often.html" rel="nofollow noreferrer">fail early</a> manner is more important than the performance hit </li>
  <li>(4) Returning <code>Map&lt;String,String&gt;</code> is sufficient (rather than returning <code>HashMap&lt;String, String&gt;</code>) </li>
  <li>(5) The key and value type args are not generic (like <code>HashMap&lt;String, ArrayList&lt;String&gt;&gt;</code>) </li>
  </ul>
  
  <p>(1), (2) and (3) are symptoms of my work environment, beyond my control.  (4) and (5) are compromises I've made because I haven't found good ways to overcome them yet.</p>
  
  <p>(4) Is difficult to overcome because even if a <code>HashMap.class</code> was passed into a <code>Class&lt;M&gt;</code> I haven't been able to figure out how to return a <code>M&lt;K, V&gt;</code>.  So I return a <code>Map&lt;K, V&gt;</code>.</p>
  
  <p>(5) Is probably an inherent limitation of using <code>Class&lt;T&gt;</code>.  I'd love to hear alternative ideas.</p>
  
  <p>Despite those limitations can you see any problems with this code?  Am I making any assumptions I haven't identified?  Is there a better way to do this?  If I'm reinventing the wheel please point me to the wheel. :)</p>
  
  <pre><code>public class CheckedCast {
  
      public static final String LS = System.getProperty("line.separator");
  
      /** Check all contained items are claimed types and fail early if they aren't */
      public static &lt;K, V&gt; Map&lt;K, V&gt; castToMapOf( 
              Class&lt;K&gt; clazzK,    
              Class&lt;V&gt; clazzV,
              Map&lt;?, ?&gt; map) {
  
          for ( Map.Entry&lt;?, ?&gt; e: map.entrySet() ) {
              checkCast( clazzK, e.getKey() );            
              checkCast( clazzV, e.getValue() );            
          }
  
          @SuppressWarnings("unchecked")
          Map&lt;K, V&gt; result = (Map&lt;K, V&gt;) map;        
          return result; 
      }
  
      /** Check if cast would work */
      public static &lt;T&gt; void checkCast(Class&lt;T&gt; clazz, Object obj) {
          if ( !clazz.isInstance(obj) ) {
              throw new ClassCastException(
                  LS + "Expected: " + clazz.getName() +
                  LS + "Was:      " + obj.getClass().getName() +
                  LS + "Value:    " + obj
              );
          }
      }
  
      public static void main(String[] args) {
  
          // -- Raw maps -- //
  
          Map heterogeneousMap = new HashMap();
          heterogeneousMap.put("Hmm", "Well");
          heterogeneousMap.put(1, 2); 
  
          Map homogeneousMap = new HashMap();
          homogeneousMap.put("Hmm", "Well");
  
          // -- Attempts to make generic -- //
  
          //Unsafe, will fail later when accessing 2nd entry
          @SuppressWarnings("unchecked") //Doesn't check if map contains only Strings
          Map&lt;String, String&gt; simpleCastOfHeteroMap = 
                      (Map&lt;String, String&gt;) heterogeneousMap;  
  
          //Happens to be safe.  Does nothing to prove claim to be homogeneous.
          @SuppressWarnings("unchecked") //Doesn't check if map contains only Strings
          Map&lt;String, String&gt; simpleCastOfHomoMap = 
                      (Map&lt;String, String&gt;) homogeneousMap;  
  
          //Succeeds properly after checking each item is an instance of a String
          Map&lt;String, String&gt; checkedCastOfHomoMap = 
                      castToMapOf(String.class, String.class, homogeneousMap);
  
          //Properly throws ClassCastException
          Map&lt;String, String&gt; checkedCastOfHeteroMap = 
                      castToMapOf(String.class, String.class, heterogeneousMap); 
          //Exception in thread "main" java.lang.ClassCastException: 
          //Expected: java.lang.String
          //Was:      java.lang.Integer
          //Value:    1
          //    at checkedcast.CheckedCast.checkCast(CheckedCast.java:14)
          //    at checkedcast.CheckedCast.castToMapOf(CheckedCast.java:36)
          //    at checkedcast.CheckedCast.main(CheckedCast.java:96)
  
      }
  }
  </code></pre>
  
  <p>Some reading I found helpful:</p>
  
  <p><a href="https://stackoverflow.com/questions/6093363/generic-factory-with-unknown-implementation-classes">Generic factory with unknown implementation classes</a></p>
  
  <p><a href="http://www.angelikalanger.com/GenericsFAQ/FAQSections/ParameterizedTypes.html#FAQ006" rel="nofollow noreferrer">Generic And Parameterized Types</a></p>
  
  <p>I'm also wondering if a <a href="http://jackson.codehaus.org/1.0.1/javadoc/org/codehaus/jackson/type/TypeReference.html" rel="nofollow noreferrer">TypeReference</a> / <a href="http://gafter.blogspot.com/2006/12/super-type-tokens.html" rel="nofollow noreferrer">super type tokens</a> might help with (4) and (5) and be a better way to approach this problem.  If you think so please post an example.</p>