Avatar billede ppstyle Nybegynder
08. marts 2005 - 15:33 Der er 13 kommentarer og
1 løsning

Find navn på kaldene funktion i javakode ved runtime

Så er jeg tilbage med et irriterende spørgsmål. Jeg kunne godt tænke mig en feature ved dett eksempel kode:


public void fName(){

// noget java kode
System.out.println("Java kode her der fortæller at jeg er i fName");

}

Nogle bud. Bedste bud indtil videre er noget ala throw new RuntimeException()

Men det er et hack. Kender i en elegant måde evt. med reflection ?

Mvh. Daniel, God dag
Avatar billede simonvalter Praktikant
08. marts 2005 - 15:46 #1
hvis det er for alle metoder så kig på aop f.eks aspectj det er nok det nemmeste.
Avatar billede ppstyle Nybegynder
08. marts 2005 - 16:02 #2
Jeg kan godt se pointen med Aspectj, men jeg synes mit eksempel er for lille til at involvere et 3. parts produkt på den måde. Egentlig ville jeg bare høre om Java som sprog tilbød denne feature.

Mvh. Daniel
Avatar billede ppstyle Nybegynder
08. marts 2005 - 16:23 #3
Min løsning indtil videre ser således ud:

StackTraceElement[] ste = new Throwable().getStackTrace();

Men jeg syne sikke det er helt fed løsning :)

Hilsen Daniel
Avatar billede arne_v Ekspert
08. marts 2005 - 16:33 #4
Det er også en ret dyr løsning performance mæssigt.

Men det er så vidt jeg ved den eneste standard løsning.
Avatar billede simonvalter Praktikant
08. marts 2005 - 16:41 #5
selv om du ikke vil bruge aop vil jeg da lige smide løsningen aligevel ;)

public aspect Aspect {

before(): call(* *(..)) && !within(Aspect) { System.out.println(thisJoinPoint.getSignature().toShortString()); }

}



C:\>java -cp .;C:\aspectj1.2\lib\aspectjrt.jar Hello
Hello.testMethod()
Hello.testMethod2()
Avatar billede ppstyle Nybegynder
08. marts 2005 - 16:49 #6
Jeg ved godt løsningen er dyr rent performance mæssigt. Men det er kun til unit test, så 
jeg behøver ikke tage hensyn til det. Ved at undgå aspectj får jeg ikke 3. parts kode ind i mine tests. Jeg har ikke noget politisk imod apsectj, men det er bare overkill til mit problem :=)

God dag, mvh. Daniel
Avatar billede simonvalter Praktikant
08. marts 2005 - 17:05 #7
med Junit kan du bruge TestCase.getName() for at få navnet på den testcase du er i... men jeg går ud fra du ikke bruger noget test framework.
Avatar billede ppstyle Nybegynder
09. marts 2005 - 15:35 #8
Nu var det lige præcist Junit jeg brugte, og lige præcist TestCase.getName() jeg manglede :)

Den er lidt federe en new Throwable().getStackElements() etc.

Hvordan tror du de gør det i junit ?

Hilsen Daniel, der takker og bukker
Avatar billede simonvalter Praktikant
09. marts 2005 - 15:46 #9
nej jeg er ikke klar over hvordan det er implementeret men sourcen følger med så du kan selv tage et kig.
Avatar billede arne_v Ekspert
09. marts 2005 - 15:46 #10
Nu behøver man jo ikke gætte når det er open source ...

...
    private String fName;
...
    public TestCase(String name) {
        fName= name;
    }
...
    public String getName() {
        return fName;
    }
Avatar billede ppstyle Nybegynder
09. marts 2005 - 15:58 #11
Ha ha nej det ha du jo ret i. Men det var egentlig mere fordi jeg ikke gad sidde og dowloade sovsenlige nu :)

Har I iøvrigt bemærket kommentarene i javadoc:

/**
* Skrevet på 10. etage på SAS Radisson i Aarhus
*/

Altid godt med lidt humor. Jeg anede faktisk ikke det var Skandinavere der havde lavet Junit.
Avatar billede simonvalter Praktikant
09. marts 2005 - 15:58 #12
det interresante sker i  TestSuite klassen hvor den opretter testcases ud fra de metoder der starter med "test". testcases bliver oprettet med navnet som bliver fundet med http://java.sun.com/j2se/1.3/docs/api/java/lang/reflect/Method.html
så vidt jeg kan skimte.
Avatar billede ppstyle Nybegynder
10. marts 2005 - 15:55 #13
Jeg tror bare de itererer over metode navne i den pågældende klasse. Alle dem der starter med test, bliver så bare eksekveret. Egentligt ganske simpelt.

- Daniel
Avatar billede arne_v Ekspert
12. marts 2005 - 19:39 #14
Der skal faktisk lidt til for at få AspectJ til at gøre det efterspurgte.

Jeg har lavet et lille eksempel.

Test.java
---------

public class Test {
    public static void sub1() {
        System.out.println(Locator.current());
    }
    public static void sub2() {
        sub3();
    }
    public static void sub3() {
        System.out.println(Locator.current());
    }
    public static void main(String[] args) {
        sub1();
        sub2();
    }
}

Locator.java
------------

import java.util.HashMap;
import java.util.Stack;

public class Locator {
    private static HashMap data = new HashMap();
    public static void enter(String name) {
        String id = Thread.currentThread().getName();
        Stack stk = (Stack)data.get(id);
        if(stk == null) {
            stk = new Stack();
            data.put(id, stk);
        }
        stk.push(name);
    }
    public static void leave() {
        String id = Thread.currentThread().getName();
        Stack stk = (Stack)data.get(id);
        stk.pop();
    }
    public static String current() {
        String id = Thread.currentThread().getName();
        Stack stk = (Stack)data.get(id);
        return (String)stk.peek();
    }
}

LogEnterAndLeave.aj
-------------------

aspect LogEnterAndLeave {
    pointcut alltrace() : call(* *.*(..)) && !within(LogEnterAndLeave) && !within(Locator) && !call(* Locator.*(..));
    before() : alltrace() {
        Locator.enter(thisJoinPoint.getSignature().toString());
    }
    after() : alltrace() {
        Locator.leave();
    }
}

kørsel
------

C:\>ajc Test.java Locator.java LogEnterAndLeave.aj

C:\>java Test
void Test.sub1()
void Test.sub3()
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester