2013-08-09 25 views
5

ich etwas entlang der Linien von habe:"Unexpected token" mit niedrigerem begrenzt Wildcard (Java)

interface Foo<T> { 
    //... lines [0,45]... 

/*line 46*/ <R, X super T&R> List<X> weave(R value); 
    //... 
} 

Aber IntelliJ berichtet:

  1. Fehler: (46, 18) java: > erwarteten
  2. Fehler: (46, 19) Java: illegaler Beginn des Typs
  3. Fehler: (46, 26): Java '(' erwartet
  4. Fehler: (46, 28), Java: < identifier> erwartet
  5. Fehler: (46, 29) java: 'l' erwartet
  6. Fehler: (46, 43) java: < identifier> erwartet

Was ist das Problem? Darf ich einen Namen nicht an eine untere Grenze binden? Oder darf ich nur einen R&X Ausdruck in einer oberen Grenze verwenden?

Ändern es

interface Foo<T> { 
    //... lines [0,45]... 

/*line 46*/ <R> List<? super T&R> weave(R value); 
    //... 
} 

ergibt

  1. Fehler (46, 31) Java:> erwartet
  2. Fehler (46, 32): Java '(' erwartet
  3. Fehler (46, 33) java: illegaler start des typs
+0

@gerttman FYI Ihre Antwort war richtig. Der Downvoter und die Leute, die den Downvote begründeten, verwechselten Wildcards mit Typparametern. "Sie können eine Typvariable nicht als super deklarieren": http://stackoverflow.com/questions/2800369/bounding-generics-with-super-keyword "Sie können nicht zwei Grenzen deklarieren, die selbst generische Typparameter sind" : http://stackoverflow.com/questions/13101991/java-generics-make-generic-to-exends-2-interfaces –

Antwort

3

Von meinem Lesen der Spezifikation, super kann nur mit einem Platzhalter verwendet werden und kann nicht in einer Typvariablen erfasst werden; siehe JLS 4.5.1. Ebenso ist & nur gültig in Typ Variablen, nicht Typ Argumente, und Typ Variablen können super nicht verwenden.

Nachdem ich darüber nachgedacht habe, hier meine Erklärung: Der Grund für eine Typvariable ist, explizites Casting zu eliminieren, um die Typensicherheit zu verbessern. Wenn Sie einen Typparameter als super Foo deklarieren, sagen Sie, dass der Parameter beliebig Superklasse Foo in Ordnung ist. Das bedeutet, dass es alles bis einschließlich Object sein kann und Sie daher keine sichere Möglichkeit haben, irgendetwas von den Objekten anzunehmen, deren Typ diese Grenze erfüllt, und daher gibt es keinerlei Informationen innerhalb einer benannten Typvariablen; Sie nur Wildcard und kann hashCode() oder toString() aufrufen, aber nichts typspezifisch.

+0

Können Sie an irgendeine Möglichkeit denken, die Semantik anzugeben, die ich versuche? –

+0

Können Sie die Semantik erklären? O :-) Es ist nicht leicht, aus deinem Code zu schließen. Was soll 'interface Foo' tun? Was ist mit 'weben'? Was beabsichtigen Sie, indem Sie in einem Rückgabetyp "Super" verwenden? – chrylis

+0

Foo ist nur eine Sammlung von T. "weben" ist eine Verallgemeinerung des Musters, das man gewöhnlich benutzt, um die Elemente eines Arrays zu drucken: [1, 2, 3].weben (",") würde zurückkehren [1, ",", 2, ",", 3,]. Mit anderen Worten, es gibt "this" zurück, außer dass der Parameter zwischen jedem Element gespleißt ist. Was die Semantik der Generika angeht, möchte ich eine Liste des am meisten abgeleiteten Supertyps für R und T zurückgeben, obwohl ich mir nicht sicher bin, ob ein solcher Mechanismus existiert. Ich möchte das tun, damit die zurückgegebene Liste in irgendeiner Weise (und nicht nur eine unformatierte Liste) für die Typsicherheit parameterisiert wird. –