2015-04-25 44 views
6

In Java < 8, "unsichere" Objekte (Objekte oder null) zurückkehrte, konnte ich Rückgabetyp in Unterklasse spezialisieren:Optional <> und Rückgabetyp Verengung

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

In Java 8, wenn ich will zu meinen API „sicherer“ zu machen, sollte ich Optional<A> anstelle von „rohen“ A zurück:

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

Aber nicht kompilieren! Weil Optional<B> keine Unterklasse von Optional<A> ist.

Wie soll ich dieses Problem lösen?

Antwort

3

Sie könnten Platzhalter verwenden.

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

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

Ich hätte es nur Optional<B> gemacht, aber mit Optional<? extends B> einem anderen Schnittstelle Sub erweitern kann und das gleiche zu tun.

Persönlich denke ich, das ist ein bisschen ein Durcheinander, und es wäre vorzuziehen, einfach A oder B, oder null wo notwendig zurückgeben.

+0

Es gibt [Schulen des Denkens] (http://Stackoverflow.com/q/9561295/1079354), die glauben, dass das Verschieben in das 'Optional'-Paradigma weniger NPEs erzeugt und zwingt, besser darüber nachzudenken, welche Verhaltensweisen der Code hat hat eigentlich. – Makoto

+0

@Makoto Ich kenne die Argumente, und ich stimme ihnen zu (ich benutze "Optional" die ganze Zeit). Mein Kommentar am Ende war über die Kombination '?' Und 'Optional' –

+0

Die Obergrenze ist nicht das Schlimmste, was passieren könnte; Es kann durchaus berechtigte Gründe dafür geben, warum man das tut. Der Grund, warum ich so reagiert habe, war, dass du "null" erwähnt hast. – Makoto

2

Ändern Sie Ihre Eltern Grenzen Platzhalter zu verwenden:

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

Der Grund, dass der Code nicht jetzt ist auf die Tatsache zurückzuführen ist, dass Generika arbeiten unveränderlich sind. B ist-ein A, aber Optional<B> ist kein Optional<A>.