Android Studio: неоднозначный вызов метода - PullRequest
0 голосов
/ 11 марта 2019

Я создаю собственный Matcher для запуска тестов Espresso на стороннем ToggleSwitch. Я хочу, чтобы Espresso знал, какой переключатель «выбран» в этих переключателях.

Android Studio подчеркивается красной частью пользовательского класса matcher. Подвох в том, что проект успешно собран и тест успешно выполнен.

Я не могу понять,

  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;

А ошибка гласит:

Неоднозначный вызов метода. Оба метода getCheckedPosition () в ToggleSwitch и getCheckedPosition () в ToggleSwitch соответствуют

Ответы [ 2 ]

1 голос
/ 11 марта 2019

Ошибка заключается в классе ToggleSwitch .Класс объявляет свойство var checkedPosition : Int? = null, для которого Kotlin будет генерировать геттер и сеттер с именами getCheckedPosition и setCheckedPosition.Тем не менее, класс также объявляет функции с этими именами.

Давайте рассмотрим байт-код 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

В то время как метод получения компилируется в:

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

Сигнатуры методов отличаются из-за типов возвращаемых данных, поэтому JVM принимает оба метода, но для вызывающей стороныэто неоднозначно.

Вместо этого класс должен переместить функциональность getter и setter в объявления get() и set() свойства.

0 голосов
/ 11 марта 2019

удаление неоднозначного геттера из класса ToggleSwitch.kt должно заставить его работать как положено:

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