2017-08-12 1 views
-1

In Java 8 Stream Bibliothek, fand ich eine interessante Frage in gleichen Methoden in java.util.stream.Stream:Warum der leeren() -Methode hat (ohne Parameter) von java.util.stream.Stream in Java 8 einen Typparameter enthält

  • static <T> Stream<T> empty()

Wie wir sehen können, dass es keine Parameter in der Methode ist Unterschrift. Nach meinem Verständnis, in diesem Fall sollte es nicht Typ Parameter - <T> - nach der optionale Spezifikation - static sein. Zum Beispiel wird in der Methode Optional<T> findAny() kein Typ Parameter wie erwartet angegeben.

Also könnte jemand erklären, warum static <T> Stream<T> empty() einen Typparameter enthält?

+3

siehe Typ Inferenz: https://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html –

+0

@ Holi-Java Ich glaube nicht, dass dies viel mit Typ Inferenz zu tun hat ... – Eugene

+0

@Eugene hey, der Abschnitt [Zieltypen] (https://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html#target_types) beschreibt es genau.Ich denke, dass OP beginnt, generisch zu lernen, also wünsche ich mir, dass er zuerst die Typinferenz sieht. :) –

Antwort

2

Lassen Sie uns zunächst unsere eigene Art erklären, um besser zu verstehen, warum:

static interface Stream<T> { 

    public static Stream<T> empty() { // will not compile here 
     return new Stream<T>() { 
     }; 
    } 

} 

Wie dieser Code jetzt ist, wäre es nicht kompilieren, sagen, dass can not make a static reference to the non-static type T, die IMO durchaus Sinn macht. Dies geschieht, weil der statische Kontext völlig unabhängig von Typparametern ist (dies sollte Ihre erste Frage beantworten).

Um dies zu beheben, müssen wir den Typ Parameter an die Methode hinzuzufügen:

public static <T> Stream<T> empty() { // notice the extra <T> 
    return new Stream<T>() { 
    }; 
} 

Das gerade übersetzt werden können, aber es ist ein verstecktes Problem - die Klasse T und das Verfahren T sind völlig unabhängig und habe keine Beziehung zwischen ihnen.

Dies wie dies mit der exakt gleichen Effekt hätte geschrieben werden können (und sauberer IMO):

public static <R> Stream<R> empty() { 
    return new Stream<R>() { 
    }; 
} 

weil Sie diese haben: return new Stream<R>()... wir effektiv R und T gleichwertig gemacht haben, kann dieser Grund ist, kann die warum sie immer noch T in der Deklaration von empty() statt einer anderen Art verwendet.

Nun wollen wir die gleiche Logik zu findAny gelten:

public <T> Optional<T> findAny(); 

dies eine Warnung generiert wird -, dass Sie die <T> verstecken, die auf Klassenebene (Stream<T>) und dem in der Methode deklariert wird. Das passiert, weil findAnyist nicht statische und es verwendet den Typ Parameter bereits deklariert - die Sie verstecken, indem Sie eine andere <T>, die keine Beziehung mit der einen Form der Klassenstufe haben würde.

Verwandte Themen