È possibile forza il paramet ERS essere dello stesso tipo effettuando le seguenti operazioni:
// the first class, A<K>:
class A<K> {
void f(K x) {}
}
// the second class, defining the method with generic type parameters
class Test {
<T> void foo(A<T> a, T x) {
a.f(x); // now it works!
}
}
// a third class, that uses the above two:
class Main {
public static void main(final String... args) {
final Test test = new Test();
final A<String> a = new A<>();
test.foo(a, "bar");
}
}
Quello che fa è: il metodo foo
definisce un parametro di tipo generico T
e lo usa per far rispettare che il parametro K
tipo della classe A
deve corrispondere il tipo di x
, il secondo parametro di foo
.
Si potrebbe anche imporre restrizioni su <T>
se lo si desidera e se ha senso per il proprio problema, ad esempio <T extends Bar> void foo(A<T> a, T x) {...}
o con super
. Lo si vorrebbe se, come Joni chiesto su un commento nella domanda, X
è in realtà un tipo e non un parametro di tipo: si utilizzerà <T extends X> void foo(...)
.
Dopo aver mostrato più codice, il problema diventa chiaro.
Il metodo .get()
del contenitore restituisce un'istanza di A<? extends K>
. Pertanto, il parametro type dell'istanza ottenuta da .get()
non è stato specificato completamente. Di solito, non è un ottimo progetto restituire un tipo così non specificato. Per una presentazione video con Joshua Bloch, l'autore di Effective Java e molte API e funzionalità in Java, che mostrano come migliorare tale API, controllare questo: http://www.youtube.com/watch?v=V1vQf4qyMXg&feature=youtu.be&t=22m. A esattamente 25'36 ", Joshua Bloch dice" non tentare di usarli [tipi di caratteri jolly] sui valori di ritorno ", e lo spiega in un secondo momento, in pratica non si ottiene più flessibilità nell'usarli e basta dolorosamente difficile per gli utenti dell'API per farvi fronte (avete appena sentito gli effetti di farlo ...)
Per risolvere, si potrebbe semplicemente provare a cambiare la firma di .get()
a A<K> get()
, quindi la classe contenitore sarebbe:
public class Container<K> {
A<K> get() {
return new A<K>();
}
}
Dal momento che non sa che sta tornando get()
un'istanza di A<K>
, non c'è ragione per usare la firma più vecchio: si fa semplicemente perdere le informazioni che già conosci !
E se ancora non funziona, il problema potrebbe essere da qualche altra parte, e avresti bisogno di mostrare ancora più codice ... o meglio ancora, fai altre domande!:)
X è un parametro di classe o di tipo? – Joni