Methodenaufruf mit generischem Rückgabetyp in Java

8

In C ++ können Sie den Rückgabetyp einer Funktion in einem Parameter angeben, zB:

C ++

%Vor%

Gibt es eine Entsprechung in Java, um den Rückgabetyp anzugeben, ohne zusätzliche Klassenargumente hinzuzufügen?

Java

%Vor%     
Jason 27.02.2013, 17:21
quelle

3 Antworten

16

Es ist vollkommen in Ordnung, eine Methode mit der Signatur public <T> T getDate() zu deklarieren.

Es ist jedoch unmöglich zu implementieren die Methode, die das zurückgibt, was Sie wollen. Was eine Methode zur Laufzeit macht, kann nicht allein von ihrem Typparameter abhängen, weil sie ihren Typparameter nicht kennt.

Um eine Intuition dafür zu erhalten, sollten Sie sich darüber im Klaren sein, dass jeder mit Generics geschriebene Code auch äquivalent geschrieben werden kann, ohne Generika zu verwenden, indem einfach generische Parameter entfernt und gegebenenfalls Umwandlungen eingefügt werden. Das ist "Typ löschen".

Um zu sehen, ob Ihre Methode in Generics möglich ist, fragen Sie einfach, wie würden Sie es ohne Generika machen:

%Vor%

Wenn Sie es ohne Generics nicht schaffen, können Sie es auch nicht mit Generics machen.

C ++ - Vorlagen sind völlig anders. Für Vorlagenfunktionen und -klassen generieren C ++ - Vorlagen eine separate Kopie der Funktion oder Klasse für jedes mit ihr verwendete Typargument. d.h. der Compiler nimmt den Vorlagencode und "kopiert und fügt ihn" in mehrere Versionen ein, die jeweils getrennt sind. Daher ist jede Kopie des Codes für ein bestimmtes Typargument spezifisch und kann diesen Typ daher zur Laufzeit verwenden.

Aus diesem Grund muss C ++ - Vorlagencode in Quellform verfügbar sein, damit Sie ihn verwenden können - es gibt keine "kompilierten" Vorlagen. In Java kann jedoch eine kompilierte generische Klasse verwendet werden. Generische Klassen und Methoden in Java nehmen nichts von den Typen an, auf denen sie verwendet werden können.

    
newacct 27.02.2013, 20:09
quelle
7

Okay, jetzt mit der Bearbeitung, um klarzustellen, dass der Code von T ... abhängig ist.

Nein, in Java gibt es nichts Einfaches, um dies zu erreichen - aufgrund von Typ-Löschen, wie Ihre Frage erwähnt. Sie können Class<T> übergeben:

%Vor%

... aber Sie können nichts tun, was vom "Wert" von T selbst zur Ausführungszeit abhängt, da das einfach nicht bekannt ist. Generics ist in Java leider etwas anämisch: (

BEARBEITEN: Vor der Bearbeitung, um den Code von T ... abhängig zu machen.

Es kommt nur darauf an, das Argument type anders anzugeben:

%Vor%

Ich habe immer die Methode "Argumente direkt vor den regulären Argumenten platzieren" bevorzugt, aber da gehen wir ...

EDIT: Wie rgettman darauf hinweist, wird type inference hier sowieso das Richtige für Sie tun, so dass Sie in vielen Fällen nicht brauchen , um die Typargumente anzugeben. Manchmal tust du das auch.

    
Jon Skeet 27.02.2013 17:25
quelle
1

Bei Arrays.asList muss manchmal der Rückgabetyp angegeben werden. Java versucht, den Rückgabetyp basierend auf den allgemeinen Supertypen aller Argumente einzugrenzen, aber manchmal benötigen Sie einen bestimmten Typ. Zum Beispiel

%Vor%

Hier gibt Arrays.asList eine List<Integer> zurück und Sie erhalten einen Compiler Fehler. Um eine List<Number> zurückzugeben, müssen Sie den generischen Typ angeben.

%Vor%     
rgettman 27.02.2013 17:36
quelle

Tags und Links