Java泛型

Java泛型,java,generics,casting,Java,Generics,Casting,我想实现一个方法,该方法将对象作为参数,将其强制转换为任意类型,如果失败,则返回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(Obj

我想实现一个方法,该方法将
对象
作为参数,将其强制转换为任意类型,如果失败,则返回
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;
    }
}
publicstaticvoidmain(字符串[]args){
甲、乙类;
a=Main.staticCast(新字符串(“B”));
}
公共静态类MyClass{
}
公共静态T staticCast(对象参数){
试一试{
if(arg==null)返回null;
T结果=(T)arg;
返回结果;
}捕获(可丢弃的e){
返回null;
}
}

不幸的是,
staticCast()
函数的主体中从未抛出/捕获类强制转换异常。Java编译器似乎生成了函数
String staticCast(Object arg)
,其中有一行
String result=(String)arg即使我明确地说模板类型应该是
MyClass
。有什么帮助吗?谢谢。

你不能随心所欲。。。至少不是这样。编译器删除了所有信息,因此您最终将(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);
    }
}
Class.forName("YourClass").cast(obj);
公共类主
{
公共静态void main(字符串[]args)
{
字符串a;
MyClass b;
a=静态转换(新字符串(“B”),String.class);
b=静态转换(新字符串(“b”),MyClass.class);
系统输出打印项次(a);
}
公共静态类MyClass
{
}
公共静态T staticCast(对象参数,最终类clazz)
{
//编辑-oops忘记处理null。。。
如果(arg==null)
{
返回(空);
}
//对Class.cast的调用,正如mmeyer所做的,可能会更好…可能更好。。。
if(arg.getClass()!=clazz)
{
//给了你对Ben S的回答。。。
返回(空);
//抛出新的ClassCastException(“无法将“+arg.getClass()+”强制转换为“+clazz”);
}
返回((T)arg);
}
}

<代码> > p>不要将java泛型错误地C++模板。只有一个staticCast方法是用不同类型的擦除调用的,而不是每个T调用一个

根本不使用泛型,我会这样写:

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;
}
publicstatict staticCast(对象参数,类){
if(arg!=null&&class.isAssignableFrom(arg))
{
T结果=class.cast(arg);
返回结果;
}
返回null;
}
你是说喜欢

比如:

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);
    }
}
Class.forName("YourClass").cast(obj);
应该做你想做的事


请注意,这很难闻,可能是设计不佳的标志。

由于泛型类型信息在运行时被擦除,因此转换为泛型类型的标准方法是使用
对象:

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;
}

我同意Ben的观点,但我更喜欢以下符号:

MyClass.class.cast(obj);

顺便说一下,您应该只捕获ClassCastException,而不是Throwable。捕捉可丢弃物会导致严重的问题。我明白了,所以T是演员阵容中的一个对象。我希望为每个T使用一个单独的方法,将参数转换为(T),如果失败,将捕获异常,而不是抛出异常。根据PaulTomblin(以下帖子)的说法,这不会发生。谢谢。问题是,如果失败,它将抛出类强制转换异常。它与代码:(YourClass)对象相同,每次使用该行代码时,都会在错误时抛出一个异常,您必须检查该异常。我想在cast()方法中捕获并隐藏该异常。您想要asSubclass还是getConstructor().newInstance().cast?我忘记了CCE是一个RuntimeException,不需要catch块,或者我本来会像您的第二个方法一样执行该操作。您能详细说明为什么Java编译器不生成函数MyClass staticCast吗(Object arg);当我在a=Main.staticCast(新字符串(“B”))行中显式指定类型T时,我显式地告诉它……我认为链接到一些阅读资料会很好。@Budric:试试。另外,搜索标记为[java][泛型]的问题.isAssignableFrom应该是isInstance,不需要检查null。如果我错了,请纠正我,但我认为isAssignableFrom会找到给定类的子类,而不仅仅是那些类型完全相同的子类?使用Class.isInstance会更直接。嗯,clazz?这像klass吗?isInstance会只有当对象是clazz的实例时才有效,如果它是clazz的子类则不起作用。isAssignableFrom将处理任何可强制转换到clazz的对象,即使是子类。@Paul:Javadocs说,“此方法是Java语言instanceof运算符的动态等效方法。如果指定的对象参数为非null,则此方法返回true,并且可以强制转换为此类对象表示的引用类型,而不会引发ClassCastException。”