我想实现一个以Object
为参数的方法,将其强制转换为任意类型,如果失败则返回null
。这是我到目前为止所做的:
public static void main(String[] args) {
MyClass a, b;
a = Main.<MyClass>staticCast(new String("B"));
}
public static class MyClass {
}
public static <T> T staticCast(Object arg) {
try {
if (arg == null) return null;
T result = (T) arg;
return result;
} catch (Throwable e) {
return null;
}
}
不幸的是,类型强制转换异常永远不会被抛出/捕获到staticCast()
函数的主体中。似乎Java编译器生成函数String staticCast(Object arg)
,其中你有一行String result = (String) arg;
,即使我明确地说模板类型应该是MyClass
。有帮助吗?感谢。
答案 0 :(得分:10)
因为泛型类型信息在运行时被擦除,所以转换为泛型类型的标准方法是使用Class
对象:
public static <T> T staticCast(Object arg, Class<T> clazz) {
if (arg == null) return null;
if (!clazz.isInstance(arg))
return null;
T result = clazz.cast(arg);
return result;
}
然后这样称呼:
a = Main.staticCast("B", MyClass.class);
答案 1 :(得分:6)
你不能做你想要的......至少不是这样。编译器删除了所有信息,因此您最终将(T)作为演员中的对象 - 并且可以正常工作。
问题是以后你正在做MyClass =(String)对象;这是不允许的。
您绕过了编译器检查并使其在运行时失败。
那你究竟想做什么呢?如果你告诉我们你为什么要这样做,我们可能会告诉你Java的做法。
鉴于您的评论,您可以尝试以下方式:
public class Main
{
public static void main(String[] args)
{
String a;
MyClass b;
a = staticCast(new String("B"), String.class);
b = staticCast(new String("B"), MyClass.class);
System.out.println(a);
}
public static class MyClass
{
}
public static <T> T staticCast(Object arg, final Class clazz)
{
// edit - oops forgot to deal with null...
if(arg == null)
{
return (null);
}
// the call to Class.cast, as mmeyer did, might be better... probably is better...
if(arg.getClass() != clazz)
{
// Given your answer to Ben S...
return (null);
// throw new ClassCastException("cannot cast a " + arg.getClass() + " to a " + clazz);
}
return ((T)arg);
}
}
答案 2 :(得分:4)
你的意思是Class<T>.cast(Object obj)
?
类似的东西:
Class.forName("YourClass").cast(obj);
应该做你想做的事。
请注意,这是非常臭的,可能是设计不佳的迹象。
答案 3 :(得分:1)
不要将Java泛型误认为是C ++模板。只有一个staticCast方法被调用不同类型的擦除,而不是每个T都有一个。
根本不使用Generics,我会这样写:
public static void main(String[] args) {
MyClass a, b;
a = (MyClass)Main.staticCast(new String("B"), MyClass.class);
}
public static class MyClass {
}
public static staticCast(Object arg, Class class) {
if (arg != null && class.isAssignableFrom(arg))
return arg;
return null;
}
或者从另一个答案中窃取,使用泛型:
public static <T> T staticCast(Object arg, Class<T> class) {
if (arg != null && class.isAssignableFrom(arg))
{
T result = class.cast(arg);
return result;
}
return null;
}
答案 4 :(得分:1)
我同意本,但是,我更喜欢以下符号:
MyClass.class.cast(obj);