Kan jag anropa en metod via ett namn lagrat i t.ex. en ArrayList?
List testapa = new ArrayList();
testapa.add("MinMetod()");
något.bra(testapa.get(1));
Att ovanstående kod inte är rätt sätt har jag räknat ut iaf :OO
10 svar · 537 visningar · startad av pettsson
Kan jag anropa en metod via ett namn lagrat i t.ex. en ArrayList?
List testapa = new ArrayList();
testapa.add("MinMetod()");
något.bra(testapa.get(1));
Att ovanstående kod inte är rätt sätt har jag räknat ut iaf :OO
Nej, du kan inte använda det på det sättet. Men du kan ju lagra klasser i en lista och sedan anropa metoder från den?
list.add( new MinKlass( "Ett värde" ) );
list.get( 1 ).metodenIKlassenMinKlass();
Hmm... Klurigt, ska fundera på om det skulle kunna funka
Om du gör som Spin skriver så måste du typomvandla också, det är en Object som retuneras från en lista
list.add( new MinKlass( "Ett värde" ) );
((MinKlass)list.get( 1 )).metodenIKlassenMinKlass();
/Viktor
Pfft, här räknade jag med att pettson skriver i v1.5 och med generics:
List<MinKlass> list...
:p
Nä, helt riktigt Viktor.
Jo, det vore ju fint, men jag brukar faktiskt vänta med att använda programvara tills den kommit ut ur beta (utom min egen då ;) )
Jag förstår inte riktigt varför du vill göra det, men visst går det att göra :).
Hemligheten heter reflection, kika på java.lang.reflect.
Jag slängde ihop lite kod som exemplifierar hur du använder Method-klassen för att göra det du vill, exemplet försöker plocka upp metoderna från det aktuella klassobjektet och sedan köra metoden mot det aktuella objektet utan parametrar.
Method.invoke() returnerar ett Object-objekt med resultatet från metoden som körts.
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
public class Test {
public String methodFoo() {
return "I am method Foo";
}
public String methodBar() {
return "I am method Bar";
}
public void test() throws Exception {
ArrayList methodNames = new ArrayList();
methodNames.add("methodFoo");
methodNames.add("methodBar");
Iterator i = methodNames.iterator();
while(i.hasNext()) {
String methodName = (String)i.next();
Method m = this.getClass().getMethod(methodName, null);
Object result = m.invoke(this, null);
System.out.println("Result from method "+methodName+"="+result);
}
}
public static void main(String[] args) {
Test t = new Test();
try {
t.test();
} catch(Exception e) {
e.printStackTrace();
}
}
}
sgtpepper skrev:
Jag förstår inte riktigt varför du vill göra det, men visst går det att göra :).
Jag kan säga att när man håller på med automattestning och regressionstestning av program så är detta exakt det man vill göra. Skicka in en bunt metodanrop och parametrar tillsammans med förväntat resultat och se vad du får tillbaka...
Oerhört praktiskt. Har sparat 100-tals timmar testning, timmar som man kan lägga på nyttiga saker, som att svara på frågor på webForum.
Lime skrev:
sgtpepper skrev:
Jag förstår inte riktigt varför du vill göra det, men visst går det att göra :).
Jag kan säga att när man håller på med automattestning och regressionstestning av program så är detta exakt det man vill göra. Skicka in en bunt metodanrop och parametrar tillsammans med förväntat resultat och se vad du får tillbaka...
Oerhört praktiskt. Har sparat 100-tals timmar testning, timmar som man kan lägga på nyttiga saker, som att svara på frågor på webForum.
Tack för upplysningen, men jag är trots min rad ovan medveten om att det finns flera områden där reflection är väldigt användbart och använder det själv både för test och i andra sammanhang där ramverk behöver info om en klass/objekts egenskaper, t.ex i databaspersisteringslager.
Vad jag ville veta var vad pettson ville uppnå med arbetssättet, reflection är inte alltid att fördra, det beror ju helt på vad man vill göra och använder man det fel kan det bli ruskigt märklig kod.
Om du nu sparat 100-tals timmar som du lägger på webForum-svarande så borde det ju ha varit du som levererade svaret, inte jag? :p
Vad jag gör (kanske lite overkill, men det funkar ju fint :) ) är en meny till en serie program. Menyn ändras allteftersom, och jag ville slippa ha en switch case hanterare i varje program.
Tackar för lösningen då den fungerar utmärkt. Undrar dock varför jag inte kan anropa private/protected metoder?
Du kan aldrig anroppa privata funktioner utifrån en klass, dessa kan du bara anroppa när du är inna i klassen.
/Viktor