Kotlin: доступ к общедоступному полю из класса Java, который также переопределяет общедоступный метод получения с тем же именем - PullRequest
5 голосов
/ 14 марта 2019

У меня есть класс Java (который я не могу редактировать, потому что он автоматически генерируется Thrift), определенный следующим образом:

public class TheirException extends Throwable {
  public String message;

  public TheirException(String message) {
    this.message = message;
  }

  public String getMessage() {
    return this.message;
  }
}

Однако, если я пытаюсь получить message от Kotlin, getMessage() недоступен и выдает ошибку Unresolved reference. Попытка использовать поле message приводит к следующей ошибке:

Ошибка: (470, 30) Котлин: Неоднозначность разрешения перегрузки:
публичное окончательное сообщение var: String! определено в com.example.TheirException
public open val сообщение: String? определено в com.example.TheirException

Однако, если я вместо этого сделаю:

(exception as Throwable).message

разрешается нормально.

Почему приведение к Throwable здесь необходимо, почему getMessage() недоступно и что вызывает двусмысленность?

1 Ответ

2 голосов
/ 14 марта 2019

Неопределенность вызвана тем, что message является публичным.Kotlin переводит каждого получателя в свойство , даже если нет вспомогательных полей .Если вы добавите еще одну функцию в этот класс:

public String getSecondMessage() {
  return "second message"; // Note that this getter does not rely on a field
}

Вы можете получить к нему доступ в Kotlin следующим образом:

TheirException("message").secondMessage

Если message общедоступно и есть функция getMessage()Kotlin создает 2 геттера, и на сайте вызовов вы знаете, что использовать.В вашем примере 2 получателя будут иметь одинаковое поведение, но это не всегда так.

Когда вы приводите свой класс к Throwable, вы явно указываете компилятору, что этот класс имеет сигнатуру Throwable, что означает, что вы определяете, что должен быть только один message геттер, это разрешаетдвусмысленностьОбратите внимание, что у Kotlin есть собственное определение Throwable (это будет важно позже).

Теперь вы можете спросить, почему нет функции getMessage().Это потому, что вы кастуете на Throwable, а не java.lang.Throwable.Определение Kotlin Throwable не имеет getMessage()

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