How to call a method without repeat from other methods in java

坚强是说给别人听的谎言 提交于 2019-12-21 18:32:26

问题


For example, I have thousands of method like:

AA() {
    ...
}  
BB() {
    ...
}  
CC() {
    ...
}  
etc ...

Now I want to call a method printCurrentMethodName() on the beginning of each method. That means,

AA() {
    printCurrentMethodName();
    ...
}  
BB() {
    printCurrentMethodName();
    ...
}  
CC() {
    printCurrentMethodName();
    ...
}  
etc ...

Including printCurrentMethodName() on the start of thousands of method is time consuming.

Is there any way that I can call printCurrentMethodName() on the beginning of each methods without repeating it in those thousands of method?

(I can't use something like @Before or @BeforeMethod annotation, because it will call printCurrentMethodName() before entering AA() and so it will not print the method name as expected)


回答1:


If you only want to print the names of the test methods then you could create a JUnit rule that is similar to the TestName rule

public class PrintTestName extends TestWatcher {
  @Override
  protected void starting(Description d) {
      System.out.println(d.getMethodName());
  }
}

and use it in your test

public class YourTest {
  @Rule
  public final PrintTestName printTestName = new PrintTestName();

  @Test
  public AA() {
    ...
  }

  ...



回答2:


You can use java.lang.reflect.InvocationHandler for this purpose.

Before any of the methods inside your class is called (AA,BB,CC etc.) the invoke method of your InvocationHandler is called. Inside the invoke method you have access to the actual method that was called and you can add additional logic, like printing the name the called method, to be executed before or after the actual method is called.

Code example:

public class PrintClassName {
    public static void main(String[] a) {
        Service srv = (Service) Proxy.newProxyInstance(
                PrintClassName.class.getClassLoader(),
                new Class<?>[]{Service.class},
                new PrintingMethodNameHandler(new ServiceImpl())
            );

        srv.doNothing();
    }
}

interface Service {
    void doNothing();
}

class ServiceImpl implements Service {
    public void doNothing() { }
}

class PrintingMethodNameHandler implements InvocationHandler {
    private Service service;

    public PrintingMethodNameHandler(final Service service) {
        this.service = service;
    }

    @Override
    public Object invoke(final Object proxy, final Method method,
            final Object[] args) throws Throwable {
        System.out.println(method.getName());
        return method.invoke(service, args);
    }
}



回答3:


You could use a regex to insert this call on every function.

Replace (\w+\(\w*\)\s*\{) with $1\nprintCurrentMethodName();




回答4:


How about using AspectJ annotations.

For ex-

Common AspectJ annotations : 1.@Before – Run before the method execution

2.@After – Run after the method returned a result

3.@AfterReturning – Run after the method returned a result, intercept the returned result as well.

4.@AfterThrowing – Run after the method throws an exception

5.@Around – Run around the method execution, combine all three advices above.

This may solve your problem . You can use this to call a method when it is returned,

You may follow this tutorial.




回答5:


It is simple, Put this line in your method.

System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName());


来源:https://stackoverflow.com/questions/31239200/how-to-call-a-method-without-repeat-from-other-methods-in-java

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!