Параметризованных типов Java

Я хотел бы реализовать метод, который принимает 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;
    }
}

к сожалению, исключение класса cast никогда не выбрасывается / не попадает в тело . Кажется, Java-компилятор генерирует функцию String staticCast(Object arg) в котором у вас есть строка String result = (String) arg; хотя я прямо говорю, что тип шаблона должен быть MyClass. Любой помочь? Спасибо.

5 ответов


поскольку общие сведения о типе стираются во время выполнения, стандартный способ приведения к общему типу-это


вы не можете делать то, что хотите... по крайней мере, не так. Компилятор удалил всю информацию, поэтому вы оказались с (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<T>.cast(Object obj)?

что-то типа:

Class.forName("YourClass").cast(obj);

должен делать в значительной степени то, что вы хотите.

имейте в виду, что это довольно вонючий, хотя и, вероятно, признак плохого дизайна.


Не путайте Java generics с шаблонами 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;
}

Я согласен с Беном, однако предпочитаю следующую нотацию:

MyClass.class.cast(obj);