Avoiding cast with a generics hack

Say you have a method that returns Object that you need to cast to the actual type. Collection classes have always worked with Objects and required casting, but retrofitting with generics helped reduce this. Methods can be generic too, and we can use a quasi-hack to pre-cast the Object return values. The more I work with scripting languages, the more I realize how verbose Java is, and techniques like this help a lot with reduction of repetition and cruft.

One example is the case in a Spring (or other DI framework) app where you don’t have control over the creation of instances that need Spring-managed resources and cannot use DI (for example JSP custom tags, which are created by the container). In this case we need to pull resources instead of having them pushed.

So we create a utility class that has access to the ApplicationContext, e.g.:

import org.springframework.beans.factory.annotation.Required;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public final class SpringContext implements ApplicationContextAware {

  private static final SpringContext INSTANCE = new SpringContext();

  private ApplicationContext context;

  private SpringContext() {
    // singleton
  }

  public static SpringContext instance() {
    return INSTANCE;
  }

  public Object getBean(final String name) {
    return context.getBean(name);
  }

  @Required
  public void setApplicationContext(final ApplicationContext c) {
    context = c;
  }
}

and map it in Spring using:

<bean class='com.myco.myapp.spring.SpringContext' factory-method='instance' />

Usage of getBean requires a cast to the actual type, e.g.:

UserDAO dao = (UserDAO)SpringContext.instance().getBean("userDao");

But we’ve already specified that the type is UserDAO, so we can amend getBean to be generic:

@SuppressWarnings("unchecked")
public <T> T getBean(final String name) {
  return (T)context.getBean(name);
}

and then the client code becomes:

UserDAO dao = SpringContext.instance().getBean("userDao");

This is also useful for methods that return a base class. For example, suppose you have a hierarchy of user classes; an abstract User base class with concrete subclasses Subscriber and Admin. If you have this method in UserDAO:

User findUserByUsername(String username);

then usage looks like:

Admin admin = (Admin)dao.findUserByUsername("bob");

As before, we’ve specified Admin twice, so we can change the method to:

<T extends User> T findUserByUsername(String username);

and this simplifies the calling code to:

Admin admin = dao.findUserByUsername("bob");

Of course this is just syntactic sugar – if the cast is invalid it will still fail.

3 Responses to “Avoiding cast with a generics hack”

  1. […] document.write(“”); } )() Continuing on the generics discussion here, I’ve been using a pattern that I’ve seen discussed in the blogosphere to reduce redundancy in […]

  2. […] document.write(“”); } )() Continuing the discussion from here and […]

  3. anjan bacchu says:

    hi there,

    the application I currently work on can use your tip.

    thank you.

    BR,
    ~A

Creative Commons License
This work is licensed under a Creative Commons Attribution 3.0 License.