Auf Thema antworten

Ich gehe mal davon aus dass es eine Uebungsaufgabe ist. Wenn das keine Uebungsaufgabe, ist musst du deinen genauen Anwendungsfall sagen (wie [USER=61094]@kneitzel[/USER] schon meinte).




Gehen wir das mal durch, nehmen wir an wir haben einen Klasse mit drei Methoden:


[CODE=java]

public class Test {

    public void doSomething1() { }

    public void doSomething2() { }

    public void doSomething3() { }

}

[/CODE]


Wenn wir hier jetzt die Aufrufe innerhalb dieser Klasse zaehlen wollen wuerden, muessten wir drei Variablen anlegen zum zaehlen:


[CODE=java]

public class Test {

    private int doSomething1CallCounter = 0;

    private int doSomething2CallCounter = 0;

    private int doSomething3CallCounter = 0;


    public void doSomething1() {

        doSomething1CallCounter++;

    }


    public void doSomething2() {

        doSomething2CallCounter++;

    }


    public void doSomething3() {

        doSomething3CallCounter++;

    }

}

[/CODE]


Wie wir merken, wird das sehr schnell sehr wiederholend und langweilig, desweiteren haben wir dann in unserer Klasse sehr viele Variablen herum liegen. Wir koennten zum Beispiel die Variablen zusammen fassen in ein Array:


[CODE=java]

public class Test {

    private int[] callCounter = new int[3];


    public void doSomething1() {

        callCounter[0]++;

    }


    public void doSomething2() {

        callCounter[1]++;

    }


    public void doSomething3() {

        callCounter[2]++;

    }

}

[/CODE]


Das reduziert zwar die Variablen, aber die Verwendung ist jetzt nicht mehr so toll (welche Methode hat Index 2?). Wir koennten dann noch Konstanten mit Name und Index anlegen, aber dann sind wir wieder zurueck bei vielen Variablen. Eine Map waere eine bessere Loesung, da wir dann per Namen auf die Zahlen zugreifen koennten. Der Nachteil ist, dass wir dann einen Integer verwenden muessen anstelle eines [ICODE]int[/ICODE]s, was die Handhabung etwas erschwert. Daher werden wir uns eine Methode zum zaehlen anlegen:


[CODE=java]

public class Test {

    private Map<String, Integer> callCounters = new HashMap<>();


    public void doSomething1() {

        countCall("doSomething1");

    }


    public void doSomething2() {

        countCall("doSomething2");

    }


    public void doSomething3() {

        countCall("doSomething3");

    }

   

    private void countCall(String methodName) {

        Integer callCounter = callCounters.get(methodName):

       

        if (callCounter == null) {

            callCounter = Integer.valueOf(0);

        }

       

        callCounter = Integer.valueOf(callCounter.intValue() + 1);

       

        callCounters.put(methodName, callCounter);

    }

}

[/CODE]


Ist relativ mehr geworden (ja, Teile davon wuerde der Compiler automatisch machen mit Boxing/Autoboxing, aber ich mache so etwas nicht, verklagt mich). Der Vorteil hier ist dass wir sehr einfach neue Methoden hinzunehmen koennen zum zaehlen, wir muessen einfach nur die Methode aufrufen. Der Nachteil ist, dass wir den Methodennamen duplizieren, wenn wir die Methode einmal umbenennen, koennten wir den Aufruf vergessen. Fuer eine Ubuengsaufgabe waere eine solche Loesung aber absolut ausreichend.


Wenn man auch nicht den Methodennamen im Aufruf warten will, kann man noch per Reflection auf den aktuellen Callstack zugreifen. Da sind wir aber schon sehr tief in einer komplett anderen Thematik, aber der Vollstaendigkeit halber:


[CODE=java]

public class Test {

    private Map<String, Integer> callCounters = new HashMap<>();


    public void doSomething1() {

        countCall();

    }


    public void doSomething2() {

        countCall();

    }


    public void doSomething3() {

        countCall();

    }

   

    private void countCall(String methodName) {

        StackTraceElement[] callStackTrace = Thread.currentThread().getStackTrace();

        StackTraceElement callingMethod = callStackTrace[2];

        String methodName = callingMethod.getMethodName();


        Integer callCounter = callCounters.get(methodName):

       

        if (callCounter == null) {

            callCounter = Integer.valueOf(0);

        }

       

        callCounter = Integer.valueOf(callCounter.intValue() + 1);

       

        callCounters.put(methodName, callCounter);

    }

}

[/CODE]


Das setzt natuerlich immer vorraus dass die Methode direkt aufgerufen wird.



Oben