How to avoid using a Triple Cast

OMG: Using a Triple Cast

We've all faced situations where a seemingly simple task spirals into unexpected complexity. In 2010, I encountered such a scenario and ended up writing a triple cast! 😅

The challenge: I needed a method that would return the default value for a given type. Here's the first approach I wrote at the time:

        
public static <T> T defaultValue(Class<T> clazz) {
    if (clazz == byte.class) 
        return (T) (Byte) (byte) 0;
    // Other primitive types handled...
    return null;
}
    

Yes, this is casting madness! Let’s break it down:

  • (byte) 0: Initializes the default value for the byte primitive type.
  • (Byte): Wraps the primitive into its wrapper type, Byte.
  • (T): Casts it to the generic type T.

While functional, this approach is overly verbose, difficult to read, and frankly, not very elegant. So, I decided to refactor it into something cleaner and more efficient:

        
    // Using double brace initialization here simplicity of this example
    // in reality, helper methods create an immutable Map
    static final Map<Class<?>, Object> DEFAULT_MAP = new HashMap<>() {{
        put(boolean.class, false);
        put(byte.class, (byte) 0);
        put(short.class, (short) 0);
        put(char.class, (char) 0);
        put(int.class, 0);
        put(long.class, 0L);
        put(float.class, 0.0f);
        put(double.class, 0.0d);
    }};
    
   /**
     * Returns the default value for the given class.
     *
     * @param type The class for which to return the default value.
     * @return The default value for the given class.
     */
    public static <T> T defaultValue(Class<T> type) {
        return (T) DEFAULT_MAP.get(type);
    }
    

Here’s why this approach is better:

  • Centralized Logic: All default values are stored in a map (DEFAULT_MAP), making it easy to add or modify default values.
  • Reduced Casting: While casting still occurs, it’s simplified and separated into manageable steps.
  • Improved Readability: The intent of the method is much clearer and easier to understand for future developers.
  • Efficiency: The map is pre-populated during static initialization, ensuring quick lookups at runtime.

Conclusion

While triple casts might work in a pinch, they often lead to code that is harder to read and maintain. By leveraging structures like maps and focusing on immutability, we can achieve solutions that are not only more elegant but also more robust and flexible. Remember, clear and concise code is always worth the extra effort!

Comments

Popular posts from this blog

Java is Very Fast, If You Don’t Create Many Objects

System wide unique nanosecond timestamps

Comparing Approaches to Durability in Low Latency Messaging Queues