Android Studio:不明确的方法调用

Android Studio: Ambiguous Method Call

我正在为第 3 方 ToggleSwitch 上的 运行 Espresso 测试创建自定义匹配器。我想让 Espresso 知道这些开关中哪个开关是 "selected"。

Android Studio 在自定义匹配器 class 的红色部分加了下划线。问题是,项目构建成功,测试运行成功。

我想不通

  1. 为什么会出现模棱两可的方法调用错误

  2. 如果有语法错误,构建成功的原因。

这是代码

import android.view.View;
import com.llollox.androidtoggleswitch.widgets.ToggleSwitch;
import org.hamcrest.Description;
import androidx.test.espresso.matcher.BoundedMatcher;

public class ToggleSwitchMatcher extends BoundedMatcher<View, ToggleSwitch> {

    private final int togglePos;

    static ToggleSwitchMatcher inPosition(int togglePos){
        return new ToggleSwitchMatcher(togglePos);
    }

    private ToggleSwitchMatcher(final int togglePos){
        super(ToggleSwitch.class);
        this.togglePos = togglePos;
    }

    @Override
    protected boolean matchesSafely(ToggleSwitch item) {
        return item.getCheckedPosition() == togglePos;
    }

    @Override
    public void describeMismatch(Object item, Description description) {
        super.describeMismatch(item, description);
    }

    @Override
    public String toString() {
        return super.toString();
    }

    @Override
    public void describeTo(Description description) {
        description.appendText("with checked position:").appendValue(togglePos);
    }
}

这一行中的括号加了下划线

    return item.getCheckedPosition() == togglePos;

错误指出:

Ambiguous Method Call. Both getCheckedPosition() in ToggleSwitch and getCheckedPosition() in ToggleSwitch match

从 class ToggleSwitch.kt 中删除模棱两可的 getter 应该可以使其按预期工作:

fun getCheckedPosition() : Int {
    return checkedPosition ?: -1
}

错误在于ToggleSwitchclass。 class 声明 属性 var checkedPosition : Int? = null,Kotlin 将为此生成一个 getter 和一个 setter,名称为 getCheckedPositionsetCheckedPosition.但是,class 也声明了具有这些名称的函数。

让我们检查一下 Kotlin 字节码,看看它编译的原因。 属性 编译为:

public final getCheckedPosition()Ljava/lang/Integer;
@Lorg/jetbrains/annotations/Nullable;() // invisible
 L0
 LINENUMBER 12 L0
 ALOAD 0
 GETFIELD com/llollox/androidtoggleswitch/widgets/ToggleSwitch.checkedPosition : Ljava/lang/Integer;
 ARETURN
L1
 LOCALVARIABLE this Lcom/llollox/androidtoggleswitch/widgets/ToggleSwitch; L0 L1 0
 MAXSTACK = 1
 MAXLOCALS = 1

而 getter 编译为:

public final getCheckedPosition()I
 L0
 LINENUMBER 43 L0
 ALOAD 0
 GETFIELD com/llollox/androidtoggleswitch/widgets/ToggleSwitch.checkedPosition : Ljava/lang/Integer;
 DUP
 IFNULL L1
 INVOKEVIRTUAL java/lang/Integer.intValue ()I
 GOTO L2
L1
 POP
 ICONST_M1
L2
 IRETURN
L3
 LOCALVARIABLE this Lcom/llollox/androidtoggleswitch/widgets/ToggleSwitch; L0 L3 0
 MAXSTACK = 2
 MAXLOCALS = 1

方法签名因 return 类型而不同,因此 JVM 接受这两种方法,但对于调用者来说是不明确的。

class 应该将 getter 和 setter 功能移动到 属性 的 get()set() 声明中。