Archief - Java Generic Methods/Constructors

Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.

Squealer

Legacy Member
Iets dat ik nooit heb begrepen, waar ik niet genoeg uitleg over vind en wat ik zelf nog nooit gedaan heb in mijn code, is een constructie als deze:

Code:
class GenericClass {
  private double val;

  [B]<T extends Number> GenericClass(T arg) {[/B]
    val = arg.doubleValue();
  }

  void showValue() {
    System.out.println("val: " + val);
  }
}

Een generic method of constructor dus.


Wat ik dan zou doen, is dit:

Code:
class GenericClass {
  private double val;

  [B]GenericClass(Number arg) {[/B]
    val = arg.doubleValue();
  }

  void showValue() {
    System.out.println("val: " + val);
  }
}
Gewoon een referentie naar de superclass gebruiken dus.

Wat is nu de meerwaarde van de generieke versie?



Nog een voorbeeld uit de java tutorial van sun:
Code:
public class Box<T> {
    private T t;          

    public void add(T t) {
        this.t = t;
    }

    public T get() {
        return t;
    }

   [B] public <U> void inspect(U u){[/B]
        System.out.println("T: " + t.getClass().getName());
        System.out.println("U: " + u.getClass().getName());
    }

    public static void main(String[] args) {
        Box<Integer> integerBox = new Box<Integer>();
        integerBox.add(new Integer(10));
        integerBox.inspect("some text");
    }
}

Wat is het nut hiervan, als het volgende even goed compileert en dezelfde output heeft, namelijk
T: java.lang.Integer
U: java.lang.String

Code:
...
    [B]public void inspect(Object u){[/B]
        System.out.println("T: " + t.getClass().getName());
        System.out.println("U: " + u.getClass().getName());
    }

    public static void main(String[] args) {
        Box<Integer> integerBox = new Box<Integer>();
        integerBox.add(new Integer(10));
        integerBox.inspect("some text");
    }
}

WHiSPy

Legacy Member
Euh, even kort statement: een constructor heeft geen return parameter, dus die kan je niet generiek maken met die return parameter. :)

MajorWintersEC

Legacy Member
Een ander voorbeeldje, misschien is het dan duidelijk:
Code:
package be.xios.Generics;

public class MaximumTest {

	
	public static <T extends Comparable<T>> T maximum(T x, T y, T z){
		T max = x;
		if(y.compareTo(max)>0)
			max=y;
		
		if(z.compareTo(max)>0)
			max=z;
		
		return max;
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println(maximum(3,4,5));
		System.out.println(maximum("pear","apple","orange"));
	}

}
Ceneric classes en methods worden oa gebruikt om minder code te moeten schrijven.

KenSpectre

Legacy Member
@MajorWintserEC: Die package herken ik overal :p xios diepenbeek.
Vorig jaar dan gehad? Van ramaekers of van hermans?

OT: Sterker nog: minder code en ge hoeft nie te kijke naar String, Int, Double ....
Kunt dan ingeve wa ge wilt.
(alsk me nie vegis?)

Squealer

Legacy Member
WHiSPy zei:
Euh, even kort statement: een constructor heeft geen return parameter, dus die kan je niet generiek maken met die return parameter. :)

<T extends Number> voor die constructor is geen return parameter.
Code komt van Generic Constructors : Generic MethodGenericsJava Tutorial

Of wat bedoel je?

@KenSpectre, ja dat weet ik, maar kijk naar mijn 2 non-generic manieren. Daar kunt ge ook String, Int, Double, whatever meegeven, afhankelijk van het supertype als argument

@MajorWintersEC, nee het is me nog niet duidelijk, srry :s
Wat ik had gedaan, is:
Code:
public static Comparable maximum(Comparable x, Comparable y, Comparable z){
		Comparable max = x;
		if(y.compareTo(max)>0)
			max=y;
		
		if(z.compareTo(max)>0)
			max=z;
		
		return max;
	}

EDIT:
Hmm, waar ik nu wel een voordeel in zie, is het feit dat met uw generieke versie, het returntype gelijk is aan uw argument. String in = String out, zonder cast.
Bij de non generieke versie zou je moeten Comparable naar String casten na een type check.

Is dat de enige meerwaarde van generieke methoden?

En hoe zit het dan met void methoden of generieke constructors?

MacK

Legacy Member
idd, het voordeel van die generieke versie is type safety. (Dat is uiteindelijk het voornaamste opzet van generics)

*edit* De gecompileerde code zal er trouwens uitzien als jouw laatste voorbeeld. Alleen heeft de compiler dus kunnen checken op type-safety

forloRn_

Legacy Member
In het geval van je eerste en je tweede voorbeeldje zie ik eerlijk gezegd ook niet het voordeel van generics hoor. Iemand een idee?

killgore

Legacy Member
forloRn_ zei:
In het geval van je eerste en je tweede voorbeeldje zie ik eerlijk gezegd ook niet het voordeel van generics hoor. Iemand een idee?
In dat specifiek voorbeeld zijn generics niet nodig :-).

generics zijn vooral noodzakelijk wanneer je (zoals hier gezegd) consistentheid van 1 type wilt afdwingen. Bv. je maakt een List<String> aan, dan kan je daar niets anders dan string objecten insteken of uithalen (je kan altij via downcasting werken enzo natuurlijk, maar het type dat de lijst kent is String).

Stel dat je een structuur hebt die enkel afgeleiden van string mag bevatten dan zal het zoiets zijn:

Code:
class StringList<T extends String>
{
    ...
}

Nu zal je enkel een lijst kunnen aanmaken waar zeker alles het type String heeft, dus je kan uitgaan van een zekere gegeven interface, maar nog steeds een zeer specifieke lijst maken (ik zeg maar iets, bv . een lijst van type URLString ).

Squealer

Legacy Member
killgore zei:
In dat specifiek voorbeeld zijn generics niet nodig :-).

ok dan... Ididoot dat daar dan een voorbeeld van bestaat op die website. Kverstond er mij niet aan ... :)

Voor de rest, het voordeel van generics in collections, dat snap ik allemaal. Juist die 2 voorbeelden uit men eerste post leken mij zinloos....

Het nut van een generieke methode snap ik nu ook, behalve als de methode geen return type heeft.... Dan zijn generics daar toch ook zinloos? (zie inspect() in TS)


Nog een vraag over uw StringList voorbeeld.
Wat is het verschil tussen :
class StringList<T extends String>
en
class StringList<? extends String>
Beiden staan subtypes van String of String zelf toe, maar de ene vermeldt "T", de ander de wildcard "?".
Betekenis? Nut?

EDIT: shit, "class StringList<? extends String>" compileert niet. Ja, wildcards heb ik zelf nog nooit gebezigd..
Die gebruik je enkel voor de declaratie van een variabele zeker? Niet voor een class definitie.

Emerxill

Legacy Member
-P|b-SqUeaLeR zei:
Nog een vraag over uw StringList voorbeeld.
Wat is het verschil tussen :
class StringList<T extends String>
en
class StringList<? extends String>
Beiden staan subtypes van String of String zelf toe, maar de ene vermeldt "T", de ander de wildcard "?".
Betekenis? Nut?

EDIT: shit, "class StringList<? extends String>" compileert niet. Ja, wildcards heb ik zelf nog nooit gebezigd..
Die gebruik je enkel voor de declaratie van een variabele zeker? Niet voor een class definitie.
Omdat ge hier met het definiëren van class bezig zijt.
"T" is een placeholder (identifier). T is maw het type parameter.
Bijv.
Code:
public class GenericRental<T extends Thing> {
  private List<T> rentalPool;

  public T getRental() {}

  public void returnRental(T rentedThing) {}

}

Met <? extends Thing> zegt ge tegen de compiler "hier komt iets waarvan ik niet heel zeker ben van welk type het exact is, maar check even of het op zijn minst een subclass van Thing is". Maar verder gaat ge niks doen met die "?".
"T" daarentegen gaat ge gebruiken als placeholder voor het type Object dat ge daarin steekt. Daarna gaat ge T gebruiken om te vertellen welk type het voorstelt.
Dus wat is die klasse met <? extends Thing> als het alleen wilt gebruiken voor te checken of het wel van dat type is? Niks.

Aja, waarom doet ge <? extends String> of <T extends String> subclassen van String gaat niet dus ge zijt teveel aant typen ;)
"Grammaticaal" klopt het wel maar het is nutteloos.

MajorWintersEC

Legacy Member
KenSpectre zei:
@MajorWintserEC: Die package herken ik overal :p xios diepenbeek.
Vorig jaar dan gehad? Van ramaekers of van hermans?

OT: Sterker nog: minder code en ge hoeft nie te kijke naar String, Int, Double ....
Kunt dan ingeve wa ge wilt.
(alsk me nie vegis?)
Yep Xios vorig jaar, nu laatste jaar bezig. Denk dat we java van Hermans gehad hebben.
Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.
Terug
Bovenaan