Дженерики Java - PullRequest
       5

Дженерики Java

6 голосов
/ 11 марта 2009

Я хотел бы реализовать метод, который принимает 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. Любая помощь? Благодаря.

Ответы [ 5 ]

10 голосов
/ 11 марта 2009

Поскольку информация об универсальном типе стирается во время выполнения, стандартным способом приведения к универсальному типу является объект 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);
6 голосов
/ 11 марта 2009

Вы не можете делать то, что вы хотите ... по крайней мере, не так. Компилятор удалил всю информацию, поэтому в результате вы получили (T) Object, и это работает.

Проблема в том, что позже вы делаете объект 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);
    }
}
4 голосов
/ 11 марта 2009

Вы имеете в виду, как Class<T>.cast(Object obj)?

Что-то вроде:

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

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

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

1 голос
/ 11 марта 2009

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

MyClass.class.cast(obj);
1 голос
/ 11 марта 2009

Не путайте шаблоны 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...