Warum kann nicht explizit ich die Art Argument für eine generische Java-Methode übergeben?

StackOverflow https://stackoverflow.com/questions/24991

  •  09-06-2019
  •  | 
  •  

Frage

Ich habe eine Java-Funktion definiert:

static <T> List<T> createEmptyList() {
    return new ArrayList<T>();
}

Eine Möglichkeit, es zu nennen, ist wie folgt:

List<Integer> myList = createEmptyList(); // Compiles

Warum kann ich nicht nenne es durch das generische Typargument explizit vorbei? :

Object myObject = createEmtpyList<Integer>(); // Doesn't compile. Why?

Ich erhalte den Fehler Illegal start of expression vom Compiler.

War es hilfreich?

Lösung

Wenn der Java-Compiler den Parametertyp an sich für eine statische Methode nicht ableiten kann, kann man immer passieren sie den vollen qualifizierten Methodennamen: Klasse. Methode ();

Object list = Collections.<String> emptyList();

Andere Tipps

Sie können, wenn Sie in der Art als Methodenparameter übergeben.

static <T> List<T> createEmptyList( Class<T> type ) {
  return new ArrayList<T>();
}

@Test
public void createStringList() {
  List<String> stringList = createEmptyList( String.class );
}

Methoden können nicht auf die gleiche Art und Weise genericised werden, dass ein Typ kann, so dass die einzige Option für ein Verfahren mit einem dynamisch typisierte generischen Rückgabetyp - puh, dass ein Schluck :-) ist - ist in der Art, wie ein weitergeben Argument.

Für eine wirklich ausgezeichnete FAQ auf Java Generics, sehen Angelika Langer Generika FAQ .

.
.

Follow-up:

Es wäre nicht sinnvoll, in diesem Zusammenhang macht das Array-Argument wie in Collection.toArray( T[] ) zu verwenden. Der einzige Grund, ein Array verwendet wird, gibt es, da das gleiche (vorab zugewiesene) Array verwendet wird, um die Ergebnisse zu enthalten (wenn das Array groß genug ist, um sie alle in passen). Das spart auf ein neues Array zur Laufzeit des ganzen Zeit zugewiesen wird.

Doch für die Zwecke der Bildung, wenn Sie die Array Typisierung verwenden wollen, ist die Syntax sehr ähnlich:

static <T> List<T> createEmptyList( T[] array ) {
  return new ArrayList<T>();
}

@Test
public void testThing() {
  List<Integer> integerList = createEmptyList( new Integer[ 1 ] );
}

Es war ziemlich einige Zeit, seit ich in die Teile von Java gegraben, aber ...

Warum Sie nicht tun können, es war wahrscheinlich eine Design-Wahl durch die Sprache Entwickler. Dennoch wegen der Typ Löschung von Java verwendet , die Generika-Informationen werden ohnehin bei der Kompilierung fällt gelassen, so in Ihrem Beispiel würde es schaffen genau den gleichen Byte-Code, ob Sie die Typ-Parameter hatten oder nicht.

@pauldoo Ja, Sie haben Recht. Es ist eine der Schwächen mit der Java-Generika imho.

ich Antwort, die ich auf Cheekysoft möchte auch vorschlagen, zu prüfen, wie es durch die Java Menschen selbst, wie T [] Abstract # toArray (T [] a). Ich denke, Cheekysofts Version überlegen ist, aber die Java hat man den Vorteil der Vertrautheit.

Edit: Hinzugefügt Link. Re-edit: Gefunden einen Fehler auf SO:)


Follow-up auf Cheekysoft: Nun, da es eine Liste von irgendeiner Art, die das entsprechende Beispiel zurückgegeben werden sollte sollte in etwa so aussehen:

static <T> List<T> createEmptyList( List<T> a ) {
  return new ArrayList<T>();
}

Aber ja, Objekt der Klasse vorbei ist eindeutig die bessere. Mein einziges Argument ist, dass die Vertrautheit, und in genau diesem Fall ist es nicht viel wert (in der Tat ist es schlecht).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top