«неоднозначность разрешения перегрузки», когда параметр функции отмечен как «NonNull» - PullRequest
2 голосов
/ 08 января 2020

Вот мой Kotlin (версия 1.3.61) + Java (1.8.0_201) код, который не удалось скомпилировать:

Maven:

<dependency>
    <groupId>com.google.code.findbugs</groupId>
    <artifactId>jsr305</artifactId>
    <version>2.0.1</version>
</dependency>

Test.Kt :

fun main(args: Array<String>) {
    Point().setX(1)
}

Точка. java:

import javax.annotation.Nonnull;

public class Point {
    public void setX(int x) {
    }

    public void setX(@Nonnull Integer x) {
    }
}

Не удалось скомпилировать из-за следующей ошибки:

Error:(2, 13) Kotlin: Overload resolution ambiguity: 
public open fun setX(@Nonnull x: Int): Unit defined in Point
public open fun setX(x: Int): Unit defined in Point

Если я удалил @NonNull аннотацию во второй setX функции, тогда это демо может скомпилироваться. Я думал, что Java аннотация была только дополнительными метаданными и не повлияла бы на сам код, поэтому я понятия не имел, почему здесь возникла неоднозначность.

Кроме того, я запускаю javap -s Point.class и обнаружил, что они имеют одинаковый вывод :

public void setX(java.lang.Integer);
    descriptor: (Ljava/lang/Integer;)V

Может кто-нибудь помочь объяснить, что здесь происходит? Заранее спасибо.

1 Ответ

4 голосов
/ 08 января 2020

С kotlin в действии

иногда Java код содержит информацию об обнуляемости, выраженную с помощью аннотаций. Когда эта информация присутствует в коде, Kotlin использует ее. Таким образом, @Nullable String в Java рассматривается как String? на Kotlin, а @NotNull String - просто строка. Интересный вопрос - что происходит, когда аннотации отсутствуют. В этом случае тип Java становится типом платформы в Kotlin.

Когда вы используете объявления Java из Kotlin, Java примитивных типов становятся ненулевыми типами (не типами платформ) ), потому что они не могут содержать нулевые значения.

в вашем случае первый метод имеет java тип примитива в качестве параметра и , потому что примитивы не могут быть нулевыми kotlin переводит его в

setX(x: Int)

, и поскольку второй метод содержит аннотацию @Nonnull, kotlin использует эту информацию и, следовательно, переводит метод в

setX(x: Int)

так что, как вы можете видеть для kotlin, это два разных метода с точно такой же сигнатурой, отсюда и неоднозначность.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...