Проблема с instanceof с общим внешним классом

Следующий код не компилируется:

class OuterClass<T> {

    class BaseClass { }

    class SubClass extends BaseClass { }

    public void test(BaseClass myObject) {
        boolean b = (myObject instanceof SubClass);
    }
}

Сообщение об ошибке в методе test(): "Невозможно выполнить проверку instanceof для параметризованного типа MyOuterClass.MySubClass. Вместо этого используйте форму MySubClass, так как дальнейшая информация об универсальном типе будет удалена во время выполнения"

Итак, как мне определить, относится ли переменная к типу BaseClass? Я пробовал все следующее, и они не работают:

boolean b1 = (myObject instanceof SubClass);
boolean b2 = (myObject instanceof SubClass<T>);
boolean b3 = (myObject instanceof SubClass<?>);
boolean b4 = (myObject instanceof OuterClass.SubClass);
boolean b5 = (myObject instanceof OuterClass<T>.SubClass);
boolean b6 = (myObject instanceof OuterClass<?>.SubClass);
boolean b7 = (myObject instanceof OuterClass.SubClass<T>);
boolean b8 = (myObject instanceof OuterClass.SubClass<?>);

Я думаю, что эта проблема не зависит от версии JVM, но на всякий случай я использую версию Sun 1.6.0_22-b04.


person Dan R.    schedule 27.07.2011    source источник
comment
Ваша строка для b4 должна была сработать, если вы избавились от префиксов My.   -  person highlycaffeinated    schedule 27.07.2011
comment
Вместо тестирования классов, почему бы не протестировать интерфейс? Я думаю, это должно решить вашу проблему.   -  person johnnieb    schedule 27.07.2011
comment
Спасибо, что заметили эту опечатку, с высоким содержанием кофеина; Я удалил префикс My.   -  person Dan R.    schedule 27.07.2011
comment
@Dan Дэн - если один из ответов поможет вам, пожалуйста, примите его. Спасибо.   -  person Amir Raminfar    schedule 28.07.2011


Ответы (4)


Это только частичный ответ, но если мы изменим пример следующим образом, он скомпилируется:

class OuterClass<T> {

    class InnerClass { }

    public void test(Object myObject) {
        boolean b1 = (myObject instanceof OuterClass.InnerClass);     // Works
        boolean b2 = (myObject instanceof OuterClass<?>.InnerClass);  // Also works
    }
}
person Dan R.    schedule 27.07.2011
comment
Хорошо, а в чем еще проблема? Хотите знать, почему? - person Paŭlo Ebermann; 27.07.2011

Ваш код для b4 правильный. По крайней мере для 1.6.0_23.

class OuterClass<T> {

    class BaseClass { }

    class SubClass extends BaseClass { }

    public void test(BaseClass myObject) {
        boolean b = (myObject instanceof OuterClass.SubClass);
        System.out.println(b);
    }

    public static void main(String[] args) {
        OuterClass<Integer> outerClass = new OuterClass<Integer>();
        OuterClass<Integer>.BaseClass b = outerClass.new BaseClass();
        OuterClass<Integer>.SubClass s = outerClass.new SubClass();
        outerClass.test(b);
        outerClass.test(s);
    }
}

Выход:

false
true

Java-версия:

java version "1.6.0_23"
Java(TM) SE Runtime Environment (build 1.6.0_23-b05)
Java HotSpot(TM) 64-Bit Server VM (build 19.0-b09, mixed mode)
person Nulldevice    schedule 27.07.2011
comment
это вообще ни на что не отвечает - person Amir Raminfar; 28.07.2011

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

class OuterClass<T> {

    static class BaseClass { }

    static class SubClass extends BaseClass { }

    public void test(BaseClass myObject) {
        boolean b = (myObject instanceof SubClass);
    }
}

...и вуаля! ошибки компилятора ушли с ветром

person gnat    schedule 27.07.2011

Спасибо highcaffeinated и Nulldevice за указание на то, что b4 и b6 верны.

Я обнаружил, что это ошибка в версии Eclipse, которую я использовал. (Я использовал Ганимед, и это было исправлено, когда я обновился до Гелиоса.)

Просто для протокола я зарегистрировал его как ошибка Eclipse 353354.

person Dan R.    schedule 28.07.2011