如何查明方法是否已调用给定实例。 Like "Object obj" 检查 obj 是否调用了 "equals" 方法

How to find out whether Method has called for given instance. Like "Object obj" check whether obj called "equals" method or not

我想知道是否正在为该实例调用某个对象的方法。

java可以吗?

喜欢...

class Button {
 public void focus(){}
 public void setName(){}
}

class MyTest {
public static void main(String[] args){
    Button button = new Button();
    button.focus();

    // I want to find out on button instance whether focus() or setName() is called or not.
    whetherMethodCalled(button);
    // OR
    whetherMethodCalled(button, 'focus');
    whetherMethodCalled(button, 'setName');
  }
}

EDIT:忘记添加按钮 class 是第三方 class 我无法修改...另外我想检查我的代码是否方法是否调用了给定的对象实例,基于我必须编写一些代码。

您可以模拟按钮并在 MyTest 中验证必须调用该方法的次数。使用 Mockito you can mock and stub your methods(Stubbing voids 需要与 when(Object) 不同的方法,因为编译器不喜欢括号内的 void 方法)然后使用 verify 语句验证它。

verify(mockButton, times(1)).focus();
verify(mockButton, times(1)).setName();

如果需要的地方比较多,涉及的东西比较复杂,建议使用Mockito来测试你的代码。使用它您可以验证该方法是否被调用(以及调用了多少次)

您可以在第 3 方按钮 class 上编写一个包装器 class,所有对按钮 class 的调用都将通过它进行。 这个包装器class 可以跟踪每个方法是否被调用

class ButtonCaller {

    private Button button = null;
    private boolean focusCalled;
    private boolean setNameCalled;

    public ButtonCaller() {
        button = new Button();
        focusCalled = false;
        setNameCalled = false;
    }

    public void focus() {
        button.focus();
        focusCalled = true;
    }

    public void setName() {
        button.setName();
        setNameCalled = true;
    }

    public void whetherMethodCalled(ButtonMethod method) {
        switch (method) {
        case FOCUS:
            return focusCalled;
        case SET_NAME:
            return setNameCalled;
        }
        throw new RuntimeException("Unknown ButtonMethod !!!");
    }

    public static Enum ButtonMethod {
        FOCUS,
        SET_NAME;
    }
}

为了减少额外的工作,也许使用 JConsole 或其他工具分析您的应用程序就足以显示某些方法是否具有 运行。另一种选择是使用代码覆盖工具,如 EMMA,它可以检测死代码。在 http://java-source.net/open-source/profilers and EMMA is at http://emma.sourceforge.net/.

有一个 Java 的开源分析器列表

通过一些额外的工作,AspectJ 可用于拦截方法调用而无需更改现有代码。例如,以下将拦截对 Button.focus()

的调用
@Aspect
public class InterceptButtonMethods {
  @Before("execution(* Button.focus())")
  public void beforeInvoke() {
    System.out.println("Button.focus invoked");
    incrementFocusCount();
  }
}

如果可以做更多的额外工作,有一种方法可以包装对 Button 的 focus() 和 setName() 方法的所有调用,以便它们在正常功能之外更新单独的计数器。这可以通过扩展 YourButton class 中的 Button 来完成,除了几个带有 getters、setters 和 increment 方法的 int 计数器外,它与 Button 相同;和 countingFocus() 和 countingSetName() 方法更新它们的计数器并分别调用 focus() 和 setName(),例如大纲:

Class YourButton extends Button { 
  int focusCount; 
  int setNameCount
  int getFocusCount() {return this.focusCount;}
  void setFocusCount(int counter) {this.focusCount = counter} // optional to reset counter
  void incrementFocusCount() {this.focusCount = getFocusCount() + 1;)
  ...
  void countingFocus() {
    incrementFocusCount();
    focus()
  }
  ...
}