When should I use the java 5 method cast of Class?

梦想的初衷 提交于 2019-11-28 12:02:26

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.

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.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!