Toon posts:

[JAVA] Method invocation overloading

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik heb een probleem als ik zelf mijn methodes probeer te invoken dat hij sommige methodes niet kan vinden.

Voorbeeld ik heb een methode:
getSomething(List l)

En die roep ik aan op deze manier:
Java:
1
instanceMyClass.getClass().getMethod("getSomething", parameter.getClass()).invoke(instanceMyClass, parameter);


Dan gaat het verkeerd omdat mijn parameter van het type Vector is welke dus wel de interface List implementeert.

Verder gaat de aanroep op deze manier ook verkeerd als het om subclasses gaat. Het lijkt er dus op dat deze manier van het aanroepen van een methode niet werkt met method overloading. Heeft iemand enig idee hoe ik dit kan verhelpen?

  • Confusion
  • Registratie: April 2001
  • Laatst online: 01-03-2024

Confusion

Fallen from grace

getClass() retourneert de runtime class van het object. Als je wilt zoeken naar een passende methode voor een bepaalde parameter, dan zal je de interfaces die de class implementeert stuk voor stuk langs moeten lopen; dan vind je hem wel.

Wie trösten wir uns, die Mörder aller Mörder?


  • Robtimus
  • Registratie: November 2002
  • Laatst online: 07-04 14:35

Robtimus

me Robtimus no like you

Verwijderd schreef op woensdag 08 maart 2006 @ 17:04:
En die roep ik aan op deze manier:
Java:
1
instanceMyClass.getClass().getMethod("getSomething", parameter.getClass()).invoke(instanceMyClass, parameter);
Wacht eens even, begrijp ik het goed? Je hebt een bekende instance van een bekende class. Je hebt een bekende method met parameterlist. En toch roep je die method aan dmv reflection?
Wat is er mis met gewoon "instanceMyClass.getSomething(parameter)"? (Eventueel met casten)

Of vertel je een deel van het verhaal niet?

[ Voor 5% gewijzigd door Robtimus op 09-03-2006 13:11 ]

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


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Ik neem even aan dat je wel reflection nodig hebt en dat dit alleen een voorbeeldje is om het probleem te illustreren.

Het probleem is dus inderdaad dat je alleen methoden kan vinden als je exact de *gedeclareerde* types van de parameters opgeeft. Als je die types weet, kan je die beter meegeven en dus niet de classes van de actual parameters opvragen.

Als dit echt niet voldoende is, moet er method resolution uitgevoerd worden, wat een erg duur proces is omdat er erg veel methode opgevraagd moet worden, wat stuk voor stuk veel tijd vraagt: het verkrijgen van een Method is erg duur in vergelijking met het uitvoeren van de invocation via reflection. Als je echt precies het gedrag wilt van een methode aanroep in source code, kunnen er allerlei conversies uitgevoerd worden (verzameld onder de noemer method invocation conversions) en moet je checken of de parameters subklassen zijn etc.

Dit wil je in ieder geval niet zelf implementeren. Ik weet niet of er een goede standaard implementatie ergens te krijgen is, maar meestal zitten de meest nuttige uitbreidingen wel bij Jakarta Commons. In dat geval moet je wezen bij de MethodUtils van de Jakarta Commons BeanUtils.

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • DaRKie
  • Registratie: December 2001
  • Laatst online: 05-04 15:05
reflection moet je zoveel mogelijk vermijden, zoals eerder aangehaald, reflection is duur. In de meeste gevallen kunne reflection oplossingen, aangepast worden in een design met oa interfaces.

Soms is reflection een goede manier van iets op te lossen, maar meestal is het een vorm van bad design :)

Verwijderd

Topicstarter
DaRKie schreef op donderdag 09 maart 2006 @ 21:32:
reflection moet je zoveel mogelijk vermijden, zoals eerder aangehaald, reflection is duur. In de meeste gevallen kunne reflection oplossingen, aangepast worden in een design met oa interfaces.

Soms is reflection een goede manier van iets op te lossen, maar meestal is het een vorm van bad design :)
Oh ok. Ik wist niet dat reflection duur was.

Verder heb ik deze structuur aangehouden omdat het gaat om een server aanroep vanaf de client. Deze komt in een methode terecht die vervolgens checkt welke methode hij daadwerkelijk moet aanroepen. Ik heb het met reflection gedaan omdat ik dacht dat dit sneller is dan zelf een hashmap bijhouden en de juiste methode erbij te zoeken.

Bedankt voor jullie reacties.

  • Tubby
  • Registratie: Juni 2001
  • Laatst online: 07-04 18:35

Tubby

or not to be

DaRKie schreef op donderdag 09 maart 2006 @ 21:32:
Soms is reflection een goede manier van iets op te lossen, maar meestal is het een vorm van bad design :)
Ik weet niet of je bekend bent met hibernate. Maar hibernate vetrouwd volledig op reflection, als je bezig bent met een 100% flexibel design kom je vaak niet om reflection heen. Ik ben het met je eens dat reflection vaak onnodig gebruikt wordt, maar om nou te beweren dat het "duur" is (kwa performance neem ik aan) vind ik te ver gaan.

[ Voor 17% gewijzigd door Tubby op 10-03-2006 15:12 ]

tubby.nl - Artes Moriendi - q1 - bf1942 - WoT - pubg - LinkedIN


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Tubby schreef op vrijdag 10 maart 2006 @ 15:10:
[...]
maar om nou te beweren dat het "duur" is (kwa performance neem ik aan) vind ik te ver gaan.
Het is nou eenmaal zo dat het "duur" is. Dat neemt niet weg dat je het niet kan gebruiken maar je moet het niet overal op performance critische plaatsen gaan toepassen.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • JKVA
  • Registratie: Januari 2004
  • Niet online

JKVA

Design-by-buzzword fanatic

rwb schreef op vrijdag 10 maart 2006 @ 15:34:
[...]

Het is nou eenmaal zo dat het "duur" is. Dat neemt niet weg dat je het niet kan gebruiken maar je moet het niet overal op performance critische plaatsen gaan toepassen.
Laat ik een andere reden noemen om ver bij reflection uit de buurt te blijven. Reflection stelt je in staat om encapsulation te omzeilen. Dat is ook precies de reden dat Hibernate het gebruikt, niet zo zeer omdat het flexibeler design toelaat, maar omdat je rechtstreeks properties kunt zetten.

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
private static BasicSetter getSetterOrNull(Class theClass, String propertyName) {
               
               if (theClass==Object.class || theClass==null) return null;
               
               Method method = setterMethod(theClass, propertyName);
               
               if (method!=null) {
                       if ( !ReflectHelper.isPublic(theClass, method) ) method.setAccessible(true);
                       return new BasicSetter(theClass, method, propertyName);
               }
               else {
                       BasicSetter setter = getSetterOrNull( theClass.getSuperclass(), propertyName );
                       if (setter==null) {
                               Class[] interfaces = theClass.getInterfaces();
                               for ( int i=0; setter==null && i<interfaces.length; i++ ) {
                                      setter=getSetterOrNull( interfaces[i], propertyName );
                               }
                       }
                       return setter;
               }
               
        }


Deze code staat ergens diep in de core van Hibernate. Als je nu de security iets hoger instelt (zie help van setAccessible) heeft Hibernate mogelijk een groot probleem.

Kortom, blijf eraf. :P

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


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 10:17

.oisyn

Moderator Devschuur®

Demotivational Speaker

Zie overigens ook [rml][ JAVA] String invoer methode laten activeren[/rml], iemand die precies hetzelfde probeert :)

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.


  • JKVA
  • Registratie: Januari 2004
  • Niet online

JKVA

Design-by-buzzword fanatic

rwb schreef op vrijdag 10 maart 2006 @ 15:34:
[...]

Het is nou eenmaal zo dat het "duur" is. Dat neemt niet weg dat je het niet kan gebruiken maar je moet het niet overal op performance critische plaatsen gaan toepassen.
Overigens, naast het feit dat het zeer lelijke en absoluut niet robuuste code oplevert, hoeft performance geen probleem te zijn, want die methodes kun je gewoon ergens cachen.

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


  • Tubby
  • Registratie: Juni 2001
  • Laatst online: 07-04 18:35

Tubby

or not to be

JKVA schreef op vrijdag 10 maart 2006 @ 16:16:
[...]


Laat ik een andere reden noemen om ver bij reflection uit de buurt te blijven. Reflection stelt je in staat om encapsulation te omzeilen. Dat is ook precies de reden dat Hibernate het gebruikt, niet zo zeer omdat het flexibeler design toelaat, maar omdat je rechtstreeks properties kunt zetten.

Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
private static BasicSetter getSetterOrNull(Class theClass, String propertyName) {
               
               if (theClass==Object.class || theClass==null) return null;
               
               Method method = setterMethod(theClass, propertyName);
               
               if (method!=null) {
                       if ( !ReflectHelper.isPublic(theClass, method) ) method.setAccessible(true);
                       return new BasicSetter(theClass, method, propertyName);
               }
               else {
                       BasicSetter setter = getSetterOrNull( theClass.getSuperclass(), propertyName );
                       if (setter==null) {
                               Class[] interfaces = theClass.getInterfaces();
                               for ( int i=0; setter==null && i<interfaces.length; i++ ) {
                                      setter=getSetterOrNull( interfaces[i], propertyName );
                               }
                       }
                       return setter;
               }
               
        }


Deze code staat ergens diep in de core van Hibernate. Als je nu de security iets hoger instelt (zie help van setAccessible) heeft Hibernate mogelijk een groot probleem.

Kortom, blijf eraf. :P
Deze code doet weinig meer dan via de getSetterOrNull een Method object terug halen uit de class of zijn interfaces, dat is iets heel anders als de properties direct setten. Sterker nog, als je classes maakt zonder getters en setters krijg je foutmeldingen van hibernate omdat hibernate de getters en setters nodig heeft om de properties te kunnen setten.

tubby.nl - Artes Moriendi - q1 - bf1942 - WoT - pubg - LinkedIN


  • JKVA
  • Registratie: Januari 2004
  • Niet online

JKVA

Design-by-buzzword fanatic

Dat klopt, en dat is ook precies wat ik ermee probeerde te zeggen, namelijk dat je niet echt robuuste applicaties krijgt op deze manier. Ik beweer niet dat Hibernate nooit aan die properties kan komen, maar dat het afhankelijk is van de VM en dat wil je bij voorbaat niet. (tenminste ik niet)

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


  • Robtimus
  • Registratie: November 2002
  • Laatst online: 07-04 14:35

Robtimus

me Robtimus no like you

Verwijderd schreef op vrijdag 10 maart 2006 @ 14:22:
[...]


Oh ok. Ik wist niet dat reflection duur was.

Verder heb ik deze structuur aangehouden omdat het gaat om een server aanroep vanaf de client. Deze komt in een methode terecht die vervolgens checkt welke methode hij daadwerkelijk moet aanroepen. Ik heb het met reflection gedaan omdat ik dacht dat dit sneller is dan zelf een hashmap bijhouden en de juiste methode erbij te zoeken.

Bedankt voor jullie reacties.
Is RMI geen optie? Dan kun je transparant gewoon de methodes aanroepen die je nodig hebt. Je gebruikt de server alsof deze een local object is. De rest doet de JVM voor je op de achtergrond.

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

Pagina: 1