2012-11-18 4 views
5
interface A { 
    String n(); 
} 
class B implements A { 
    @Override 
    public String n() { return "asdf"; } 
} 
interface C<T extends A> { 
    T m(T t); 
} 
class D implements C<B> { 
    @Override 
    public B m(B b) { 
     return b; 
    } 
} 

Class<C<? extends A>> x = D.class; 

есть ошибка в последней строкеПочему этот шаблон не работает?

Type mismatch: cannot convert from Class<D> to Class<C<? extends A>> 

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

B b = new B(); 
A y = x.newInstance().m(b); 

это также имеет ошибку

The method m(capture#1-of ? extends A) in the type C<capture#1-of ? extends A> is not applicable for the arguments (B) 

однако, если я использовать его без маски и захвата, он отлично работает:

A z = D.class.newInstance().m(b); 

К сожалению, im kinda застрял с этим на данный момент, любая помощь будет оценена по достоинству.

редактировать: удалено this. ссылок

редактировать: изменились й быть

Class<? extends C<? extends A>> x = D.class; 

и она работает. Однако до сих пор получаю ошибки на x.newInstance().m(b)

The method m(capture#2-of ? extends A) in the type Test.C<capture#2-of ? extends A> is not applicable for the arguments (B) 

ответ

6

Право, сосредоточившись только на последней части:.

однако до сих пор получаю ошибки на x.newInstance() м (б)

The method m(capture#2-of ? extends A) in the type 
Test.C<capture#2-of ? extends A is not applicable for the arguments (B) 

Действительно - и это имеет смысл. Потому что ничто в коде не указывает, что вы действительно получили C<B>. Весь компилятор знает, что newInstance возвратил экземпляр тип, который реализует C<X> для тип X который реализует A. Как он узнает, что это B?

Если вы хотите позвонить m(b), вы будете нуждаться в C<B>, что означает, что ваше объявление будет нужно быть

Class<? extends C<B>> x = D.class; 

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

+0

не 'B реализовать A' хотя? В этом примере у меня есть 'B', но я хочу, чтобы библиотека работала с' A'. Библиотека является предпочтительной или конфигурационной библиотекой. A - это HasPreferences, а C - сериализуемый класс предпочтений.поэтому будут подтипы каждого из них, с подклассами C , что означает, что C является объектом предпочтения для A. – aepurniet

+0

C получит A, чтобы получить информацию о конфигурации из. и также применит конфигурацию на них. может быть несколько C для A. (вот почему я templatized его таким образом, а не наоборот) – aepurniet

+0

@aepurniet: 'B' реализует' A', но параметр 'Cm' не имеет типа 'A' - это тип' T'. 'D' может рассчитывать на получение экземпляра' B', а не какой-либо другой реализации 'A'. Вот почему это вызывает проблемы. В объявлении класса > ', который упоминает' B' ... –

0

его тип небезопасный (я думаю , эти предупреждения отключены, чтобы избежать загрязнения аннотаций)

Class<? extends C> x = D.class; 
    B b = new B(); 
    A y = x.newInstance().m(b); 
    A z = D.class.newInstance().m(b); 

но он работает.

Смежные вопросы