2015-04-25 27 views
6

In Java < 8, restituendo oggetti "non sicuri" (oggetti o nullo), sono stato in grado di specializzarsi tipo di ritorno in sottoclasse:opzionale <> e tipo di ritorno restringimento

class A {} 
class B extends A {} 
interface Sup { A a(); /* returns A instance, or null */ } 
interface Sub extends Sup { B a(); } 

In Java 8, se voglio a fare il mio API "più sicuro", dovrei tornare Optional<A> invece di "raw" A:

interface Sup { Optional<A> a(); } 
interface Sub extends Sup { Optional<B> a(); } 

Ma non compila! Perché Optional<B> non è una sottoclasse di Optional<A>.

Come dovrei risolvere questo problema?

risposta

3

È possibile utilizzare i caratteri jolly.

interface Sup { Optional<? extends A> a(); } 

interface Sub extends Sup { Optional<? extends B> a(); } 

ho potuto fare solo Optional<B> ma usando Optional<? extends B> permette un'altra interfaccia di estendere Sub e fare la stessa cosa.

Personalmente, penso che questo sia un po 'un disastro, e sarebbe preferibile semplicemente restituire A o B o null se necessario.

+0

Ci sono [scuole di pensiero] (http://stackoverflow.com/q/9561295/1079354) che ritengono che il passaggio al paradigma "Optional" produca meno NPE e costringa a ragionare meglio su quali comportamenti il ​​codice in realtà ha. – Makoto

+0

@Makoto Conosco gli argomenti e sono d'accordo con loro (uso sempre 'Optional'). Il mio commento alla fine riguardava la combinazione di '?' E 'Optional' –

+0

L'utilizzo del limite superiore non è la cosa peggiore che potrebbe accadere; ci possono essere ragioni molto giustificabili sul perché si dovrebbe farlo. Il motivo per cui ho reagito nel modo in cui ho agito era perché hai menzionato "null". – Makoto

2

cambiare il vostro limiti genitore di utilizzare i caratteri jolly:

Optional<? extends A> // parent 
Optional<? extends B> // child 

La ragione per cui il codice non funziona ora è dovuto al fatto che i generici sono invarianti. B è un A, ma Optional<B> non è un Optional<A>.