2016-11-26 4 views
0

überprüfen Sie die folgende Klasse aus:Constructing Objekt der allgemeinen Klasse von String in Java

public class Range<T extends Comparable<T>> 
{ 
    public T lower; 
    public T upper; 

    public Range(String range){ 
     Scanner scanner = new Scanner(range); 
     if(scanner.hasNextInt()) 
      this.lower = scanner.nextInt(); 
     if(scanner.hasNextInt()) 
      this.upper = scanner.nextInt(); 
    } 

    public String toString(){ 
     return lower + " - " + upper; 
    } 
} 

In Konstruktor, ich versuche, ein Objekt aus einem String zu erstellen. Werte, die das erstellende Objekt enthält, liegen im String-Bereich. Die Zeichenfolge hat ein Format wie eine Zeichenfolge, die von der toString-Methode zurückgegeben wird.

Dies wird nicht so einfach funktionieren, der Fehler ist in den letzten beiden Zeilen des Konstruktors, und es heißt: "Typenkonflikt: kann nicht von int in T. konvertieren" Natürlich ... Weil der T-Typ vom Benutzer entschieden wird und Scanner.nextInt() immer int zurückgibt. Selbst wenn das funktionieren würde, würde es nur funktionieren, wenn T int ist. Aber lassen Sie uns sagen, dass es mir gut geht, wenn es nur funktioniert, wenn T int ist.

Gibt es eine Möglichkeit, ein Objekt dieser Klasse mit einem solchen String zu konstruieren, nur wenn T int ist. Ich bezweifle, dass es etwas Ähnliches wie in C++ gibt.

Erhalten Sie, was ich will, sagen wir, dass die Zeichenfolge "5 - 10" ist. Ich will niedriger 5 und oberer 10 sein, und sie müssen ints sein. Jedenfalls möglich.

+0

Wenn Sie nur Ints wollen, warum haben Sie einen generischen Typ? Mache einfach "nieder" und "oben" beide "int". – Tunaki

+0

Warum möchten Sie ** Generics ** verwenden, wenn Sie den spezifischen Typ "int" haben? – developer

+0

Ich habe diese Klasse für alle Typen gemacht, die vergleichbar sind, aber ich bekomme, dass dieser Konstruktor nur funktionieren kann, wenn Mitglieder Intars sind. Wenn T's floats sind, würde ich gerne einen speziellen Range (String Bereich) für diesen Fall machen. – Scarass

Antwort

3

Eine Möglichkeit, dies generisch zu erreichen, ist die Bereitstellung einer Function<String, ? extends T>, mit der Sie eine String zu einer Instanz von T analysieren können.

public Range(String range, Function<String, ? extends T> parser){ 
    Scanner scanner = new Scanner(range); 
    if(scanner.hasNext()) 
     this.lower = parser.apply(scanner.next()); 
    if(scanner.hasNext()) 
     this.upper = parser.apply(scanner.next()); 
} 

Beachten Sie, dass dieser Gesamtansatz nicht besonders gut ist. Zum einen können Sie keinen Bereich mit nur einer oberen Grenze erstellen. und zum anderen beschränkt es Sie auf Eingabezeichenfolgen, die durch Scanner Tokenisiert werden; und Sie wären klug, Ihre Felder final zu machen, um die netten Eigenschaften zu erhalten, die Ihnen gibt.

Sie sind viel besser dran das Parsen außerhalb der Range Klasse (oder zumindest außerhalb des Konstruktors). Zum Beispiel können Sie Optional<T> (oder vielleicht null, Schauder) nutzen jede der Grenzen darzustellen, und dann erklären Ihren Konstruktor wie so:

public Range(Optional<? extends T> lower, Optional<? extends T> upper) 

so können Sie den Bereich, den Sie wollen erstellen, verwenden Sie das Format zur Verfügung zu stellen die Grenzen, die Sie wollen - Sie konstruieren die lower und upper Instanzen vor dem Aufruf des Konstruktors, so dass Sie frei sind, diese zu konstruieren, wie Sie möchten.

Verwandte Themen