Question

Looking through some code I came across the following code

trTuDocPackTypdBd.update(TrTuDocPackTypeDto.class.cast(packDto));

and I'd like to know if casting this way has any advantages over

trTuDocPackTypdBd.update((TrTuDocPackTypeDto)packDto);

I've asked the developer responsible and he said he used it because it was new (which doesn't seem like a particularly good reason to me), but I'm intrigued when I would want to use the method.

Was it helpful?

Solution

These statements are not identical. The cast method is a normal method invocation (invokevirtual JVM instruction) while the other is a language construct (checkcast instruction). In the case you show above, you should use the second form: (TrTuDocPackTypeDto) packDto

The cast method is used in reflective programming with generics, when you have a Class instance for some variable type. You could use it like this:

public <T> Set<T> find(Class<T> clz, Filter criteria) {
  List<?> raw = session.find(clz, criteria); /* A legacy, un-generic API. */
  Set<T> safe = new HashSet<T>();
  for (Object o : raw) 
    safe.add(clz.cast(o));
  return safe;
}

This gives you a safe way to avoid the incorrect alternative of simply casting a raw type to a generic type:

/* DO NOT DO THIS! */
List raw = new ArrayList();
...
return (List<Widget>) raw;

The compiler will warn you, Unchecked cast from List to List<Widget>, meaning that in the ellipsis, someone could have added a Gadget to the raw list, which will eventually cause a ClassCastException when the caller iterates over the returned list of (supposed) Widget instances.

OTHER TIPS

The main case for doing it (IME) is when you need to safely cast in a generic class/method. Due to type erasure, you can't cast to T but if you've been provided a Class<? extends T> parameter then you can use that to cast and the result will be assignable to a variable of type T.

I can't find an example where the cast method is possible and the cast syntax not. However, looking at the code, it seems that in case the cast is not possible, the cast method throws a ClassCastException with no type information attached, whereas the cast syntax will give you some hints (as in, "could not cast Snoopy to TyrannosorusRex") :

/**
 * Casts an object to the class or interface represented
 * by this <tt>Class</tt> object.
 *
 * @param obj the object to be cast
 * @return the object after casting, or null if obj is null
 *
 * @throws ClassCastException if the object is not
 * null and is not assignable to the type T.
 *
 * @since 1.5
 */
public T cast(Object obj) {
if (obj != null && !isInstance(obj))
    throw new ClassCastException();
return (T) obj;
}

With the first form

trTuDocPackTypdBd.update(TrTuDocPackTypeDto.class.cast(packDto));

you can do this:

public void dynamicCast( Class clazz, Object o ) { 
     this.x = clazz.cast( o );
}

With the second you can't. The casting class should be hard coded.

Why would you use a variable to cast in first place? That's another question. :) The first thing that comes to mind is, you don't know ( at compile time ) the class that will be casted to.

Both of these statements are identical. Pick whichever one you find more readable. The second method is more common in my experience, and it is the once that I prefer.

I tend to use the cast method solely when I am working with reflection, and it reads nicer in that situation. All other times I find myself using the second way of casting.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top