# genericsdeklaration - Typen einschränken



## trez (13. Dez 2010)

Hallo.

Ist es Möglich die Auswahl möglicher Typen bei Genericsdeklarationen einzuschränken?

Zum Beispiel dass ich nur Zahlen (Numbers) einfügen kann die Comparable sind?

Der naive Versuch

```
public class DataSet<T extends Number implements comparable > {}
```
geht leider nicht -> Syntax error on token "implements", , expected

Aktuell reicht mir sogar Comparable - ich möchte in der Klasse die < > Operatoren anwenden können.


----------



## Marco13 (13. Dez 2010)

T extends Number, Comparable
sollte eigentlich gehen


----------



## trez (13. Dez 2010)

Marco13 hat gesagt.:


> T extends Number, Comparable
> sollte eigentlich gehen



Leider nein ...


```
public class DataSet<T extends Number, comparable> {
	private T max;

	public void add (T value) {
		if(value>max) // The operator > is undefined for the argument type(s) T, T
			this.max = value;
	}
}
```

So nebenbei die Notation mit ? ist mir total suspekt ;-)


----------



## Michael... (13. Dez 2010)

Der Operator *>* kann nur auf primitive Datentypen angewendet werden und nicht auf Objekte z.B. vom Type Number.


----------



## nrg (13. Dez 2010)

Comparable schreibt man groß

und für größer/kleiner Vergleiche von Objekten kannst du die compareTo nehmen. Deshalb macht es vermutlich auch Sinn, dass Comparable implementiert sein muss


----------



## trez (13. Dez 2010)

Ich möchte, dass meine Klasse nur mit Integer, Long, Float und ähnlichem instanziert (sagt man dem so) werden kann.

Die haben alle etwas gemeinsames - sie sind von Number abgeleitet und erweitern Comparable

Im Moment habe ich allerdings erst die Vergleiche vor, also  würde mir

```
class <T implements Comparable> {}
```

reichen, aber das geht ja leider nicht.

übrigens: wEr tipPfähler findet, darf die gerne Behalten - Eclipse korrigiert mir die dann schon 


compareTo tönt ja gut, aber wenn oben nur "T" steht, gibt es keine compareTo ;(

Ok Erkenntnis 1: < ist nicht in Comparable ....


----------



## trez (13. Dez 2010)

```
public class DataSet<T extends Comparable<T>> {}
```


----------



## nrg (13. Dez 2010)

trez hat gesagt.:


> compareTo tönt ja gut, aber wenn oben nur "T" steht, gibt es keine compareTo ;(



was meinst du denn, was Comparable erzwingt?


```
public class DataSet<T extends Comparable<T>> {
    
	private T max;
	
    public void add(T value) {
        if(value.compareTo(max) > 0)
            this.max = value;
    }
}
```


----------



## trez (13. Dez 2010)

Warst zwar einige Sekunden langsamer aber trotzdem Danke ;-)

So nebenbei - das letzte mal intensiv programmiert habe ich so vor knapp 10 Jahren in C und seither nur noch reviewed und notfalls getestet - aber wenn wichtige Leute länger in Urlaub gehen und andere krank sind .... ;-)


----------



## trez (13. Dez 2010)

Sorry, war kurz an einer Sitzung und etwas vorschnell mit Lob 

Das Folgende gibt eine null pointer Exception. this.max ist null


```
public class DataSet<T extends Comparable<T>> {
	private T max;
	public void add (T pValue) {
		if (pValue.compareTo(max)>0)
			max = pValue;
	}
}
```


und das geht auch nicht ...


```
public class DataSet<T extends Number, Comparable<T>> {
```

	- Syntax error on token ",", . expected
	- The type parameter Comparable is hiding the type Comparable<T>


----------



## nrg (13. Dez 2010)

naja. du brauchst halt noch einen Konstruktor oder eine Setter, die/der max initialisiert


----------



## nrg (13. Dez 2010)

Zum zweiten Problem:

z.B.:

```
public class DataSet<T extends Number & Comparable<T>> {
    
	private T max;
	
	public void add(T pValue) {
        if (max == null || pValue.compareTo(max) > 0)
            max = pValue;
    }
}
```

edit beachten. ist vermutlich so schöner gelöst


----------



## trez (14. Dez 2010)

Guten Morgen.



nrg hat gesagt.:


> naja. du brauchst halt noch einen Konstruktor oder eine Setter, die/der max initialisiert



Hm hm - da springt mir aber deine Signatur förmlich ins Auge ;-)

max= new T() geht natürlich nicht! T ist ja nur ein Interface (Comparable)
bzw im Fall von Number & ... abstrakt.

Also bleibt nur, das von aussen zu setzen, aber wenn ich das in der add Methode mache wird ja nur die Objektreferenz des Parameters kopiert und das ist natürlich nicht die Meinung, da sich max sonst z.b. wie ein Schlaufenindex verhalten könnte.

Beim Aufruf add(new Integer(i)) zu schreiben ist irgendwie suboptimal

Setzen über Konstruktor? Aber wie ich in der Add Methode dafür sorge dass der Inhalt und nicht die Referenz kopiert wird ist mir unklar.

Ideen?


----------



## trez (14. Dez 2010)

Ich versteh java nicht mehr


```
Integer ii = new Integer(1);
Integer j = ii;
System.out.println("i = " + ii + ", j = " + j);
ii = 2;
System.out.println("i = " + ii + ", j = " + j);
```
liefert
i = 1, j = 1
i = 2, j = 1

Ich weiss, viele sind zufrieden wenns läuft, aber ich muss immer wissen warum 

Warum wird bei der Zuweisung ganz offensichtlich ein neues Objekt angelegt?


----------



## Marco13 (14. Dez 2010)

Joa, so grob.
ii = 2;
bedeutet ungefähr so viel wie
ii = Integer.valueOf(2);
oder auch
ii = new Integer(2);

Einigermaßen passendes Stichwort wäre "Autoboxing"


----------



## trez (14. Dez 2010)

Gibt es eine verbindliche Aussage bei welchen Klassen das so gemacht wird und bei welchen nicht?


----------



## nrg (14. Dez 2010)

habe dir doch für dein erstes Problem auch ein Beispiel geschrieben.

Du prüfst in der add einfach ab, ob max null ist und wenn ja initialisierst du max mit pValue. Ansonsten prüfst du halt, ob pValue größer ist (siehe meinen letzten Beispielcode).

edit: zu deinem letzten Post: bei allen Wrappern von primitiven Datentypen (Integer, Double etc)


----------



## trez (14. Dez 2010)

Ich bin fälschlicherweise davon ausgegangen dass die Referenz kopiert würde, wie das ja meistens üblich ist, und das ginge natürlich daneben.
Das unterschiedliche Verhalten des = Operators zu überblicken ist nicht ganz einfach, wenn man von C kommt ;-)

Danke für die Hilfen.


----------

