Archief - [PROG][JAVA] Methode als argument

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.

dobber_1987

Legacy Member
Dit is de bedoeling:
in mijn Opdrachtprompt typ ik java wegen bouwBocht 50. Ik roep dus mijn programma wegen op, als argument geef ik een methode mee en de lengte van de weg. In wegen heb ik verschillende methodes (bouwRecht(int lengte), bouwBocht(int lengte),...).

Mijn vraag is dus, hoe kan je met het 1e argument een methode oproepen? Je kan dat doen met allemaal if's, maar dat is volgens mij niet de juiste oplossing, ik voel dat :) .

Emerxill

Legacy Member
Ik twijfel eraan da ge methods als argumenten kunt meegeven (ben der vrij zeker van).
Die gaan zoiezo toch als een String opgevangen worden. Vandaar in uw main String args[] staat :)

Als ge argumenten via de command prompt wilt meegeven ist meestal de bedoeling da ge weet waarvoor die argumenten dienen. Bijv arg[0] is de naam, arg[1] de voornaam,... .
Als echt ge "dynamische" argumenten wilt meegeven (wat niet de bedoeling is) kunt ge daar eventueel een code aan geven bijv: br50 voor BouwRecht(50), een loopke gebruiken voor zolang er argumenten zijn.
Dan het argument 'ontrafelen': 1e 2 chars deruithalen en die gebruiken om te testen welke method oproepen moet worden, de rest zouden getallen moeten zijn, die kunt ge dan parsen en ge zijt vertrokken :p
En natuurlijk validatie niet vergeten ;)

Alles gaat, maar tis ni echt de juiste manier van werken eh ;)
Een betere oplossing zou een GUI-ke zijn waar ge uw argumenten in veldjes kunt stoppen, maar ik vermoed dat ge nog niet zover zijt...

*edit* het gaan dus if-kes worden voor het aantal methods da ge hebt of een case... (maar dan kunt ge best geen String gebruiken om uw method te identificeren)

.Acku.

Legacy Member
dobber_1987 zei:
Mijn vraag is dus, hoe kan je met het 1e argument een methode oproepen? Je kan dat doen met allemaal if's, maar dat is volgens mij niet de juiste oplossing, ik voel dat :) .

Ik zie niet in hoe ge dat anders zou gaan doen. Kunt een onwaarschijnlijk mechanisme met reflectie opzetten en dynamische methode-calls, maar hey, waarom, aangezien uw parameters rechtsreeks mappen op methodes die je schrijft om ze te verwerken is zoiets onnodig.
Gewoon een IF dus.

dobber_1987

Legacy Member
Dus tzal dan wel met if's moeten?
If (arg[1].equals("bouwRecht")) {bouwRecht(arg[2]);}
Else if (arg[1].equals("bouwBocht")) {bouwBocht(arg[2]);}

Das wel de gemakkelijkste manier, maar als je 1000 methodes hebt...volgens mij moet er toch een andere manier zijn.

killgore

Legacy Member
Maak 1 functie waar die if's instaan he, dat verlelijkt uw gewone code dan niet, is gescheiden en makkelijk aanpasbaar.

Reflection hiervoor gebruiken lijkt mij wat belachelijk.

En als je 1000 methodes op die manier moet aanroepen dan is er iets goed fout met jouw programma (te weinig algemene methodes) of moet je er eens aan denken een gui te maken :p.

En voor de meeste ide's kan je wel zaken (macros) maken die vrij automatisch de nodige lijntjes toevoegen als jij een nieuwe methode aan het lijstje wilt toevoegen.

.Acku.

Legacy Member
Ik heb nog niet veel (geen) command-line tools gezien met duizenden verschillende methods via argumenten.

Het minste dat je wel kan doen is correct gebruik maken van static finals zoals:

private static final String ARG_BOUWBOCHT = "bouwbocht";
private static final String ARG_BOUWRECHT = "bouwrecht";

public void doAction(String arg) {
if (arg.equals(ARG_BOUWRECHT)) {...}
else if (arg.equals(ARG_BOUWBOCHT)) {...}
}

dat zorgt er beetje voor dat alles mooi bovenaan bij elkaar staat

QplQyer

Legacy Member
Wat je ook kan doen is een superklasse maken ArgumentAction, met een methode doAction ();
Vervolgens schrijf je allerlei subklassen die doAction(); implementeren en waar telkens het commando inzit dat je uitgevoerd wenst te zien wanneer je een bepaald argument meegeeft.

Dan steek je het commando op de commandline en het object dat de actie uitvoert in een Map en is het enige wat je hoeft te doen voor het gebruiken van je command-line je object opzoeken in de map aan de hand van de key en de doAction() oproepen.

Het is wat meer werk dan allemaal if's, maar een hele resem if's is niet echt de meest elegante code (+ zo koppel je een bepaald gedrag direct los van de argument-lezen en checken logica, waardoor je code gemakkelijker in een GUI te stoppen is achteraf door een bepaalde knop zijn gedrag te linken aan de doAction van een bepaald object).

En je moet je niet verlagen tot reflection, wat meestal niet echt zo'n goed idee is (maar in het geval van command-line acties lijkt me dat eerlijk gezegd niet zoveel kwaads te kunnen).
Alles is eleganter dan een if-spaghetti imo :p.

.Acku.

Legacy Member
Dat idee werkt, heb het ook ooit eens zo toegepast :)

Het is idd wel heel wat meer werk en kan mogelijk wat complicaties geven ivm uw design want uw methodes gaan in aparte klassen moeten staan

dJeez

Legacy Member
Een Map gebruiken is zelfs niet nodig, je kan een klasse ook dynamisch - at runtime dus - gaan laden via Class.forName(). En verder gebruik je dan de werkwijze die QplQyer aanhaalt. Dan heb je eigenlijk ook in 1 klap een systeem dat kan werken met dynamische plugins (uw core moet niet gewijzigd worden om extra functies toe te voegen - voorzover uw interface niet breekt na verloop van tijd uiteraard).

Zelf heb ik een dergelijke methode als spielerei ontwikkeld voor een document generatie systeem. In 't kort samengevat registreerde elke document klasse (1 klasse per type document) bij het laden een instance van zichzelf in een Hashtable van een factory object, en via dat factory object werden de documenten daarna effectief gegenereerd.

CyberOps

Legacy Member
We hebben die ooit ook es toegepast in een Java FTP server die we moesten programmeren als project. Het moest dus mogelijk zijn om de bestaande commando's aan te roepen. Het commando dat we ingaven, was dus de methodenaam. De methode die je aansprak werd dan ook getriggerd. Hoe we dat precies geflikt hebben weet ik echter niet direct meer. :(

dobber_1987

Legacy Member
Ik heb geen constructor in mn klasse. Hoe moet ik dan de klassenaam krijgen? Gewoon getClass() werkt niet.
Dan heb ik een constructor gemaakt:

public LijnGent(){
klasse = this.getClass();
}

en een methode:

static void printMethods() {
Method[] methods = klasse.getMethods();
for (int i = 0; i < methods.length; i++) {
String methodString = methods.getName();
System.out.println("Name: " + methodString);
}
}

Dat print dan iets af:
Name: main
Name: hashcode
Name: getClass
Name: wait
Name: wait
Name: wait
Name: equals
Name: notify
Name: notifyAll
Name: toString

Dat zijn wel niet echt de methodes die ik heb gemaakt. Ik heb de methodes printLijnen, printHaltes, addLijn,.....

Wat is er verkeerd aan?

Kn0t

Legacy Member
Niets. Je hebt die methodes niet zelf gemaakt, maar je erft ze wel over van de klasse java.lang.Object.

Krijg je enkel die methodes terug, of staan jouw methodes er ook tussen?

dobber_1987

Legacy Member
Ik moet dus probere een methode terug te krijgen en dan dieMethode.invoke(). Hoe krijg ik die terug? Door eenKlasse.getDeclaredMethod(String name, Class... parameterTypes). Name is gewoon de naam van je methode en Class...parameterTypes is (volgens mij) als je methode er als volgt uit ziet:
public void myMethod(String string, String string2), dan moet in die array zitten: {String.class, String.class} volgens mij, maar aub correct me if I'm wrong.
Het probleem is nu (zoals hier boven) dat de methodes van mijn klasse niet tevoorschijn komen. Als ik ze afprint met klasse.getMethods() zitten die van mij er niet bij, dus als ik, bv,
Class[] classes = { Connection.class, String.class };
klasse.getDeclaredMethod("printLijnen", classes);
dan vindt die mijn methode niet aja...
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