Typeinschränkung bei Generics

nossek

Aktives Mitglied
Hallo,

ich möchte eine generische Klasse schreiben, wobei als Typ nur Klassen erlaubt sein sollen, die von Number erben (Integer, Byte ...).

Das scheint so zu funktionieren:
Java:
public class RandSeq<T extends Number> {

gerne würde ich als Typ noch die Klasse Character erlauben. Geht das und wenn ja wie?

Danke, Gruß
 
mehrere interfaces könntest du mit & verbinden aber nachdem Character kein Interface ist, ka... hilft dir jetzt bestimmt auch nicht wirklich weiter 😉
 
Ich lehne mich nun mal etwas weit aus dem Fenster uns sage, dass das nicht geht.

Grund:
[Java]
public class RandSeq<T extends Number & Character> { //... }
[/Java]
wäre nicht wirklich sinnvoll. Du könntest dann nur Objekte, die von Number UND Character erben als Parameter verwenden. Mehrfachvererbung ist in Java ja nicht erlaubt. Deswegen gibt es gar keine solche Objekte.


Der einzige Ausweg ist über eine gemeinsame Basisklasse. Wenn ich mich recht erinnere erben Number und Character direkt von Object. Also ist es unmöglich die Typen so einzuschränken, wie du das gerne möchtest.
 
wäre soetwas eine option?
Java:
class RandSeq<T>
{
	private RandSeq() {}
	
	public static <T extends Number> RandSeq<T> createRand(Class<T> clazz)
	{
		return new RandSeq<T>();
	}
	
	public static RandSeq<Character> createRand() 
	{
		return new RandSeq<Character>();
	}
}
[c]RandSeq<Integer> intRand = RandSeq.createRand(Integer.class);[/c]
 
Zuletzt bearbeitet von einem Moderator:
Danke für die Antworten!

Kann man denn die Typisierung einer generischen Klasse erzwingen, sodaß
Java:
MeineArrayList<Integer> array;
erlaubt ist,
Java:
MeineArrayList array;
aber nicht?

und:
wie kann man innerhalb der Methoden/Konstruktoren einer generische Klasse den Typ herausbekommen? T.getClass() geht nicht. Wenn ein Objekt der Klasse T an eine Methode der generischen Klasse als Argument übergeben worden ist kann man die Klasse dieses Objektes mit .getClass rausfinden. Das geht aber eben nicht immer...

Man könnte ja vielleicht gleich im Konstruktor checken, ob der Typ zu den erlaubte Typen gehört, und wenn nicht eine Excepton werfen.
 
Ich hab keine Ahnung was genau du machen willst, aber du könntest die Typen einschränken indem du eine Klasse machst die einfach 2 ArrayLists mit den jeweiligen Typen verwaltet und funktionen auf beide bereitstellt. Also sowas in der Art:
Java:
public class NumbersAndCharacters {
	private ArrayList<Number> numbers;
	private ArrayList<Character> characters;
	
	public void add(Number n) {
		numbers.add(n);
	}
	
	public void add(Character c) {
		characters.add(c);
	}
}
 
AFAIK kann man die Typisierung nicht erzwingen (Außer mit entsprechenden Flags in der IDE, "Treat Warnings as Errors" o.ä.)

Den generischen Typ herauszubekommen ist zur Laufzeit nicht möglich. Zur Laufzeit steht da überall nur noch "Object".
 
@Tomate_Salat:
muß gestehen daß ich Dein Konstrukt nicht verstehe 😳

@shiroto
bei Deinem Vorschlag sehe ich 3 Probleme:
1. könnte die erste ArrayList ja Objekte verschiedener Number-Klassen enthalten. Es soll aber bei der Erzeugung eines Objekts eben festgelegt werden "nur Integer" oder "nur Double"...
(wenn keine Typisierung im Sinne von MeineArrayList<Integer> array; erzwungen werden kann, ist das wohl eh nicht auszuschließen)
2. Zwei ArrayLists obwohl man nur eine braucht: ist das nicht unnötiger Ballast? (zumal: es soll entweder für Numbers oder für Characters gehen, so ginge aber beides)
3. Müsste man ja ohnehin alle Methoden zweimal schreiben, sollte man da nicht besser gleich zwei Klassen schreiben, eine generische für Erben von Number, eine für Character.

Mir scheint (angesichts eurer Antworten und der Aussage von Marco13):
Java:
AFAIK kann man die Typisierung nicht erzwingen (Außer mit entsprechenden Flags in der IDE, "Treat Warnings as Errors" o.ä.)
Den generischen Typ herauszubekommen ist zur Laufzeit nicht möglich. Zur Laufzeit steht da überall nur noch "Object".
das was mir vorschwebte ist wohl nur durch Umwege zu machen, die den Code nicht eben vereinfachen (was ja die wohl Idee von Generics sein soll)

Habe aber noch eine andere Idee, werde das gleich mal versuchen...
 
shiroto's beispiel ist imho quatsch bzw. hat nichts mit deinem Problem zu tun. generics hat nicht ausschließlich mit collections zu tun...

würde Tomate_Salat's Beispiel nehmen. Was verstehst du denn daran nicht?`Du hast halt einen privaten Konstruktor und erzeugst Instanzen der Klasse RandSeq eben nicht mit dem idR öffentlichen Konstruktor sondern der Methode createRand.
 

Neue Themen


Zurück
Oben