Java: Как написать приведение, которое определяет и суперкласс и интерфейс? - PullRequest
2 голосов
/ 22 февраля 2010

В моей программе на Java происходит нечто подобное:

void f(Object o) {
    g(o);
}

<T extends MySuperClass & MyInterface> void g(T x) {
    ...;
}

Как я могу разыграть, чтобы это работало? Кажется, нет никакого способа указать и базовый класс, и интерфейс в объявлениях переменных без использования обобщений. Я не думаю, что дженерики будут работать здесь, потому что o создается динамически с использованием отражения, поэтому его фактический класс не известен во время компиляции.

(Да, я знаю, что это странная вещь, которую нужно сделать. Но мне действительно нужны функциональные возможности как суперкласса, так и интерфейса. Я думаю, что я мог бы выполнить всю проверку типов во время выполнения с instanceof, но это просто кажется, Java 1.4 ...)

Ответы [ 4 ]

3 голосов
/ 22 февраля 2010

Кажется, что нет способа вызвать «сырой» универсальный метод. Но вы можете создать объект необработанного типа (очевидно, что следующее преобразование небезопасно):

void f(Object o) {
    Caster<?> c = new Caster(); 
    g(c.cast(o)); 
}

class Caster<T extends MySuperClass & MyInterface> {
    public T cast(Object o) {
        return (T) o;
    }
}
2 голосов
/ 22 февраля 2010

Вы можете создать новый внутренний класс внутри класса, содержащий f(), вызывая g()

static abstract class MyCastingClass extends MySuperClass implements MyInterface {}

Тогда вы можете разыграть:

 g((MyCastingClass)o);

EDIT:

Это не похоже на работу.

Он позволяет вашему коду компилироваться и не имеет предупреждений, но во время выполнения вы получите ClassCastException, если ваш объект на самом деле не является экземпляром MyCastingClass

1 голос
/ 22 февраля 2010

Вы можете использовать рефлексию для вызова g, аналогично приведенному ниже, но с дополнительными проверками выбора правильного метода и обработки исключений:

Object dest_obj_containing_g = this; // Replace with your object.
Method[] methods = dest_obj_containing_g.getClass().getDeclaredMethods();
for (Method m : methods) {
  if (m.getName().equals("g")) {
    m.invoke(dest_obj_containing_g,o);
    break;
  }
}
0 голосов
/ 22 февраля 2010

Может ли это быть что-то вроде

<T extends MySuperClass implements MyInterface>

Я просто догадываюсь здесь ...

...