Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[Java] Class array, zou geparameteriseerd moeten zijn

Pagina: 1
Acties:

  • DRvDijk
  • Registratie: Juni 2001
  • Laatst online: 26-10 16:37
Hoi!

Ik ben sinds kort na een paar jaar niet gejava't te hebben weer bezig met een (groot) java project. Het gaat prima, ik kwam alleen een paar nieuwe dingen tegen, die ik redelijk onder controle heb ondertussen, zoals bijvoorbeeld de geparameteriseerde HashMap. In plaats van
Java:
1
HashMap hm = new HashMap();
moet je nu
Java:
1
HashMap<String, String>hm = new HashMap<String, String>();
doen. Nieuw voor mij (jaja, ik ben er echt lang uit geweest).

Nou ben ik iemand die overal alle warnings uit mn project wil hebben. Net ziets als in PHP altijd met error_reporting(E_ALL) willen programmeren. Ik loop nu tegen iets aan, waar ik niet weet hoe ik ermee om moet gaan. Zoeken (hier en op ons Google) werkt niet voor mij, ik kom niet uit bij wat ik wil weten, misschien omdat ik niet precies weet waarop ik moet zoeken. Dus: een vraagje :)

Ik gebruik Axis om een RPC te doen op een webservice ergens aan de andere kant van de wereld. De methode daar geeft een waarde terug, een String wel te verstaan. In de standaard tutorial van Axis staat dat ik dit als volgt op moet lossen:
Java:
1
2
3
4
5
QName op = new QName("http://service.sample/xsd", "GetIets");
String pingMessage = "Hello there!";
Object[] op = new Object[] { pingMessage };
Class[] returnTypes = new Class[] { String.class };
Object[] response = serviceClient.invokeBlocking(op, opArgs, returnTypes);
met natuurlijk de op een QName die de methode aanwijst, en opArgs een Object array met de argumenten (een String ook in dit geval, maar niet van belang voor mijn vraag).
Eclipse zeurt over regeltje nummero 4.
code:
1
Class is a raw type. References to generic type Class<T> should be parameterized


De oersimpele vraag: hoe los ik deze warning op? Leesvoer, een vinger in de juiste richting, of de oplossing worden zeer geapprecieerd! :)

[ Voor 0% gewijzigd door DRvDijk op 02-10-2007 21:15 . Reden: cencuur :> ]


  • RayNbow
  • Registratie: Maart 2003
  • Laatst online: 20:02

RayNbow

Kirika <3

Leesvoer :)

Java:
1
Class<?>[] returnTypes = new Class[]{String.class};

Ipsa Scientia Potestas Est
NNID: ShinNoNoir


  • Robtimus
  • Registratie: November 2002
  • Laatst online: 13:40

Robtimus

me Robtimus no like you

Merk op dat je er soms gewoon niet aan ontkomt om warnings te genereren. Als jij bv een array van List<Object> wil, dan kun je niet gewoon zeggen
Java:
1
List<Object>[] array = new List<Object>[10];

Je moet aan de rechterkant die <Object> weghalen, anders compilet het niet. Maar zonder <Object> krijg je weer een warning. Je kunt ook proberen te casten:
Java:
1
List<Object>[] array = (List<Object>[])new List[10];
maar dat geeft zelf ook weer een warning. Dan is er de magische annotatie
Java:
1
@SuppressWarnings("unchecked")

Die kun je voor je variabele zetten, voor de method of constructor of zelfs de hele class. Bij voorkeur nooit verder dan de method gaan ;)

More than meets the eye
There is no I in TEAM... but there is ME
system specs


  • JKVA
  • Registratie: Januari 2004
  • Niet online

JKVA

Design-by-buzzword fanatic

Als je bijv. Eclipse gebruikt, is het eenvoudig. Gewoon op de regel met de oranje/gele kringeltjes gaan staan en op ctrl + 1 drukken. of op het icoontje in de kantlijn. In het contextmenu, kun je dan kiezen voor "Add SuppressWarnings" ofzo.

Fat Pizza's pizza, they are big and they are cheezy


  • BalusC
  • Registratie: Oktober 2000
  • Niet online

BalusC

Carpe diem

Bovenstaand zou je wel kunnen oplossen door de ArrayList<Object> te extenden naar een nieuwe non-generic subklasse.
Java:
1
public class ObjectList extends ArrayList<Object> {}
die je dan weer zonder warnings in arrays kunt gebruiken
Java:
1
ObjectList[] array = new ObjectList[10];
Maar Collecties/Mappen in een array stoppen of omgekeerd is sowieso een vaag ontwerp.

  • JKVA
  • Registratie: Januari 2004
  • Niet online

JKVA

Design-by-buzzword fanatic

BalusC schreef op dinsdag 02 oktober 2007 @ 08:26:
Bovenstaand zou je wel kunnen oplossen door de ArrayList<Object> te extenden naar een nieuwe non-generic subklasse.
Java:
1
public class ObjectList extends ArrayList<Object> {}
die je dan weer zonder warnings in arrays kunt gebruiken
Java:
1
ObjectList[] array = new ObjectList[10];
Maar Collecties/Mappen in een array stoppen of omgekeerd is sowieso een vaag ontwerp.
Hmm, dan heb ik liever een warning. :+

Mja, het is alleen jammer dat je soms niet aan het gebruik van array's ontkomt, vooral als je libraries gebruikt die alleen array's slikken ofzo...

Fat Pizza's pizza, they are big and they are cheezy


  • riezebosch
  • Registratie: Oktober 2001
  • Laatst online: 31-10 11:58
IceManX schreef op maandag 01 oktober 2007 @ 23:33:
Merk op dat je er soms gewoon niet aan ontkomt om warnings te genereren. Als jij bv een array van List<Object> wil, dan kun je niet gewoon zeggen
Java:
1
List<Object>[] array = new List<Object>[10];

Je moet aan de rechterkant die <Object> weghalen, anders compilet het niet. Maar zonder <Object> krijg je weer een warning. Je kunt ook proberen te casten:
Java:
1
List<Object>[] array = (List<Object>[])new List[10];
maar dat geeft zelf ook weer een warning. Dan is er de magische annotatie
Java:
1
@SuppressWarnings("unchecked")

Die kun je voor je variabele zetten, voor de method of constructor of zelfs de hele class. Bij voorkeur nooit verder dan de method gaan ;)
Ik heb buiten school sowieso weinig met Java gedaan, maar ben wel aardig into .NET. De vraag die bij mij rijst is waarom je met 'generics' een List<Object> zou willen maken. Kan je dan niet net zo goed de non-parameterized/generic variant gebruiken? Of bestaat dat niet meer in Java?

Canon EOS 400D + 18-55mm F3.5-5.6 + 50mm F1.8 II + 24-105 F4L + 430EX Speedlite + Crumpler Pretty Boy Back Pack


  • JKVA
  • Registratie: Januari 2004
  • Niet online

JKVA

Design-by-buzzword fanatic

riezebosch schreef op dinsdag 02 oktober 2007 @ 09:17:
[...]

Ik heb buiten school sowieso weinig met Java gedaan, maar ben wel aardig into .NET. De vraag die bij mij rijst is waarom je met 'generics' een List<Object> zou willen maken. Kan je dan niet net zo goed de non-parameterized/generic variant gebruiken? Of bestaat dat niet meer in Java?
Jawel, maar dan ben je van de warning af.

Het is een beetje in de trant van: "Hee compiler, ik ben een professional, ik weet waar ik mee bezig ben. Waarschuwen is niet nodig."

Fat Pizza's pizza, they are big and they are cheezy


  • DRvDijk
  • Registratie: Juni 2001
  • Laatst online: 26-10 16:37
Thanx voor de input mensen! De <?> lijkt een goede oplossing, de warning is weg en 'het werkt'. Nou vind ik dit natuurlijk nog een beetje eng, maar dat is omdat ik mezelf nog niet goed ingelezen heb. Ga ik spoedig doen, ook thanx voor de link daarnaartoe RayNbow! :)
BalusC schreef op dinsdag 02 oktober 2007 @ 08:26:
Bovenstaand zou je wel kunnen oplossen door de ArrayList<Object> te extenden naar een nieuwe non-generic subklasse.
Java:
1
public class ObjectList extends ArrayList<Object> {}
die je dan weer zonder warnings in arrays kunt gebruiken
Java:
1
ObjectList[] array = new ObjectList[10];
Maar Collecties/Mappen in een array stoppen of omgekeerd is sowieso een vaag ontwerp.
Ik weet niet of dit in mijn geval zou werken. Misschien dat het een nettere oplossing is, maar volgens mij slikt de Axis2 methode invokeBlocking geen andere parameters dan een (wel of niet geparameteriseerde) Object array, zoals JKVA ook al zegt over externe libs.
JKVA schreef op dinsdag 02 oktober 2007 @ 09:21:
[...]

Jawel, maar dan ben je van de warning af.

Het is een beetje in de trant van: "Hee compiler, ik ben een professional, ik weet waar ik mee bezig ben. Waarschuwen is niet nodig."
Juustem, en dat vind ik zeker netter dan de @SuppressWarnings, die ik nog niet kende maar eigenlijk ook helemaal niet wil kennen. Iemand zijn signature hier op GoT was ooit "Assumption is the mother of all fuckups", en met SuppressWarnings neem je aan dat je de warnings wel kan negeren. 1+1=.. :)

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 20:54

.oisyn

Moderator Devschuur®

Demotivational Speaker

BalusC schreef op dinsdag 02 oktober 2007 @ 08:26:
Bovenstaand zou je wel kunnen oplossen door de ArrayList<Object> te extenden naar een nieuwe non-generic subklasse.
Java:
1
public class ObjectList extends ArrayList<Object> {}
die je dan weer zonder warnings in arrays kunt gebruiken
Java:
1
ObjectList[] array = new ObjectList[10];
Maar Collecties/Mappen in een array stoppen of omgekeerd is sowieso een vaag ontwerp.
't Vervelende van die oplossing is dat je vervolgens geen ArrayList<Object> in die array kunt stoppen. Of elke ArrayList<?> for that matter. Als je gewoon
Java:
1
ArrayList<?> lists[] = new ArrayList<?>[10];
doet, dan werkt dat wel gewoon.

[ Voor 10% gewijzigd door .oisyn op 02-10-2007 21:59 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Robtimus
  • Registratie: November 2002
  • Laatst online: 13:40

Robtimus

me Robtimus no like you

@DRvDijk: ben ik het niet helemaal mee eens. Soms kun je gewoon garanderen dat iets van een bepaalde generic is.

Drie voorbeelden die ik zelf gebruik:
Java:
1
2
3
4
5
// declaratie
Comparator<Object>[] comparators;

// ergens op 1 locatie de assignment
comparators = new Comparator[];

Door de declaratie wordt gegarandeerd dat, op dit punt na, comparators ook daadwerkelijk een Comparator<Object>[] is. Dan wil ik die ene warning wel negeren.

Java:
1
2
// parameter T[] src; gecontroleerd op niet null
T[] result = (T[])Array.newInstance(src.getClass().getComponentType(), size);

src is niet null, dus de component type is bekend tijdens runtime. Dat deze tijdens compile tijd T heet doet er dan niet toe; tijdens runtime is het Integer, String of wat dan ook. Ik weet dan ook zeker dat Array.newInstance een T[] (in de praktijk Integer[], String[], etc) teruggeeft. Helaas is het volgens de API een Object om zo ook primitieve arrays aan te kunnen. Nou, dan cast ik maar en vang ik de warning af.


Java:
1
MyClass<T> c = (MyClass<T>)super.clone();

Tijdens het clonen weet je zeker dat de return type van super.clone() het type van de huidige class is. Dan kun je dat ook veilig casten.

Merk ook op dat de Java API zelf vol zit met warnings aangaande generics; kijk maar eens naar de source van bv ArrayList. Deze declareert een Object[], maar bij het ophalen van waarden wordt deze gecast naar het element type. Dit kan ook, omdat de rest van de API garandeert* dat alle elementen van dat array van type E zijn.
De code:
Java:
1
2
3
4
5
public E get(int index) {
    RangeCheck(index);

    return (E) elementData[index];
}


* zolang je maar geen reflection gebruikt ;)


Natuurlijk moet je het ook niet misbruiken en bovenaan je class zetten. Ik doe het alleen maar waar het echt nodig is om de warnings weg te halen. Ik zie in de code dan door die @SuppressWarnings wel dat ik bewust een compiler warning negeer.

[ Voor 7% gewijzigd door Robtimus op 02-10-2007 21:44 ]

More than meets the eye
There is no I in TEAM... but there is ME
system specs

Pagina: 1