Tengo una clase de Java (que no puedo editar, porque Thrift la genera automáticamente) definida así:
public class TheirException extends Throwable { public String message; public TheirException(String message) { this.message = message; } public String getMessage() { return this.message; } } Sin embargo, si trato de recibir un message de Kotlin, getMessage() no está disponible y genera un error de Unresolved reference . Intentar usar el campo de message produce el siguiente error:
Error: (470, 30) Kotlin: Ambigüedad de resolución de sobrecarga:
mensaje de var final público: ¡Cadena! definido en com.example.TheirException
mensaje de valor abierto público: ¿Cadena? definido en com.example.TheirException
Sin embargo, si en cambio hago:
(exception as Throwable).messagese resuelve bien.
¿Por qué es necesario convertir a Throwable aquí, por qué getMessage() no está disponible y qué está causando la ambigüedad?
La ambigüedad se debe al hecho de que el message es público. Kotlin traduce cada getter a una propiedad, incluso si no hay campos de respaldo . Si agrega otra función a esta clase:
public String getSecondMessage() { return "second message"; // Note that this getter does not rely on a field }Puedes acceder a él así en Kotlin:
TheirException("message").secondMessage Si message es público y hay una función getMessage() , Kotlin crea 2 captadores y, en el sitio de la llamada, sabrá cuál usar. En su ejemplo, los 2 captadores tendrían el mismo comportamiento, pero no siempre es así.
Cuando lanza su clase a un Throwable , le dice explícitamente al compilador que esta clase tiene la firma de un Throwable , lo que significa que define que solo debe haber un captador de message , esto resuelve la ambigüedad. Tenga en cuenta aquí que Kotlin tiene su propia definición de Throwable (esto será importante más adelante).
Ahora puede preguntar por qué no existe la función getMessage() . Esto se debe a que está transmitiendo a Throwable y no a java.lang.Throwable . La definición de Kotlin de Throwable no tiene getMessage()