2017-02-01 4 views
3

Hallo ich habe eine Frage über Java und die Verwendung von Platzhalter mit rekursiven Generics. Ich habe die folgende SchnittstelleJava rekursive Generic und Wildcard

public interface Recursive<R extends Recursive<R>> {} 

und andere intrface, die die rekursive Schnittstelle

public interface Use<R extends Recursive<R>> {} 

verwendet nun i-Schnittstelle haben, die

public interface Base<R extends Recursive<R>> { 
    Use<R>[] getUses(); 
} 

und auf der Grundlage dieser Klasse wie folgt aussieht i a wollen abgeleitete Klasse, die einen Wildcard wie diesen verwendet

public class Derived extends Base<Recursive<?>> { 
    Use<?>[] getUses(); 
} 

was nicht erlaubt ist, aber wie kann ich sagen, dass mein generischer Typ alles ist, was passt?

+1

Was wollen Sie in der abgeleiteten Klasse tun? Wird der Code kompiliert? –

+0

'Derived erweitert Basis ' sollte genug sein. –

+0

aber dann bekomme ich eine Warnung, weil ich einen rohen Typ verwende, gibt es einen Weg, ohne diese Warnung zu bekommen? – MZuenni

Antwort

0

Das Problem ist, dass Recursive<?> die Einschränkung auf Base 's-Typ Parameter nicht erfüllt.

Wenn Sie Base<R> erweitern möchten, müssen Sie etwas für R liefern, das ist auch ein Recursive<R>. Recursive<?> ist nicht gut genug, weil der Compiler Recursive<?> extends Recursive< Recursive<?> > nicht herausfinden kann.

sie nicht wirklich Sinn machen, eine Base unbekannter Art zu erweitern, aber Sie können eine heterogene Sammlung von ihnen erklären:

Collection< Base<?> > cb; // ok for some reason 
Collection< Base< Recursive<?> > > cbr; // not ok! 

Von Ihrem Kommentar wissen wir Base wie

public abstract class Base< R extends Recursive<R> > { 
    public abstract R[] foo(); 
} 
sieht

Für jedes qualifizierende R können Sie natürlich

public class Derived< R extends Recursive<R> > extends Base<R> { 
    @Override public R[] foo() { 
     return (R[])new Object[] { r1, r2 }; 
    } 
} 
tun

aber es ist nicht klar aus Ihrem Kommentar, dass dies das ist, was Sie wollen. Weißt du, was die spezifische R ist, die Sie Derived verwenden möchten?

EDIT die folgenden kompiliert. würde das genügen?

interface Recursive< R extends Recursive<R> > {} 
abstract class Base< R extends Recursive< ? extends R > > { 
    abstract public R[] foo(); 
} 
class Derived extends Base< Recursive<?> > { 
    public Recursive<?>[] foo() { return null; } 
} 

EDIT 2 für die Änderung Anpassung an den Original-Beitrag:

interface Recursive< R extends Recursive<R> > {} 
interface Use< R extends Recursive< ? extends R > > {} 
abstract class Base< R extends Recursive< ? extends R > > { 
    abstract public Use<R>[] foo(); 
} 
class Derived extends Base< Recursive<?> > { 
    @Override public Use< Recursive<?> >[] foo() { return null; } 
} 
+0

in der Basisklasse ist eine Methode, die ein Array von R zurückgeben sollte und in der abgeleiteten Klasse muss ich 2 verschiedene Objekt zurückgeben implementiere die angegebene Schnittstelle ... also ist die Superklasse von beiden Rekursiv, die ich versuche, ein Array von ... zurückzugeben. – MZuenni

+0

die abgeleitete Klasse sollte in meinem Fall nicht generisch sein, da ich an diesem Punkt weiß, welche Werte in das Array i gehören müssen zurückkehren. Das Problem ist, dass die 2 Werte, die ich zurückgeben möchte, von unterschiedlicher Klasse sind. Also ich weiß, dass ich ein Array wie folgt zurückgeben muss: 'new Recursive [] {}' aber welchen Parameter muss ich in das generische für die Basis einfügen, so überschreibe ich die Methode korrekt beim Zurückgeben von 'Recursive []' – MZuenni

+0

Do Diese beiden Typen haben eine gemeinsame Oberklasse? –

0

Sie müssen (mit dem Recht gebunden) geben Sie Ihre Unterklasse, sonst kann der Compiler nicht behaupten, dass die Platzhalter der Klasse ist der gleiche Typ als was Ihre Methode zurückgibt, die erforderlich ist.

Versuchen Sie folgendes:

public class Derived<R extends Recursive<R>> extends Base<R> { 
    Use<R>[] getUses(); 
} 
+0

, wie ich bereits abgeleitet sayd sollte nicht generische selbst sein aber Implementieren Sie die Schnittstelle mit einem bestimmten Typ – MZuenni