java android kotlin nullable

java - ¿Debo eliminar la anulabilidad de los métodos anulados que no están anotados con anulables en una clase heredada



android kotlin (6)

No se especifican como anotaciones anulables en el código Java.

Si eso es cierto, tenga en cuenta que corre el riesgo de lanzar una NullPointerException si no se especifica como una anulación anulable en el código Java y asigne un valor nulo. elimine la nulabilidad del método anulado si no se especifica como anotación anulable en el código Java.

Para más detalles lea this también kotlinlang.org

Android 3.5.1

Estaba usando WebView y noté que cuando anulo algunos de los métodos, todos los parámetros son tipos anulables:

webview.webViewClient = object : WebViewClient() { override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean { return super.shouldOverrideUrlLoading(view, request) } }

Lo que significa que tengo que usar el operador de safe call para usarlos. Sin embargo, cuando miré la clase WebViewClient la que he anulado el método, no se especifican como anotaciones nullable en el código Java.

public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { return shouldOverrideUrlLoading(view, request.getUrl().toString()); }

Así que me quedo pensando: ¿elimino la nulabilidad del método anulado o los mantengo?


A diferencia de Kotlin, los objetos Java por defecto pueden aceptar valores nulos

La anotación @Nullable solo se usa para operaciones como analizadores de código (por ejemplo, si el parámetro @Nullable no se maneja dentro del método, mostrará una advertencia)

La anotación @NonNull se usa para especificar que el valor recibido no puede / no será nulo

if(@NonNull){ can omit ? check }else if(@Nullable){ Mandatory to put ? check }else(No annotation){ Not mandatory but put on safer side . Passing null from Java into Kotlin fun without ? will lead to NPE if(putting ? check){ java equivalent Kotlin param (@Nullable Webview view) } else{ java equivalent Kotlin param (@NonNull Webview view) } }

Consulte también esto: https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html#null-safety


A nivel de lenguaje, esto puede generalizarse:

Para una correcta interoperabilidad de Java, el código de Kotlin debe reflejar las anotaciones del código de Java.

El linter solo se queja de la falta de anotaciones en la otra dirección, por la interoperabilidad de Kotlin.

Consulte este artículo reciente sobre Cómo escribir código Kotlin compatible con Java?


La fuente de este problema proviene de la interoperabilidad entre Java y Kotlin . Hay algunas diferencias básicas de nivel de lenguaje entre Java y Kotlin que causan problemas de interoperabilidad. Android Studio proporciona algunas comprobaciones de Lint para advertirles, como Unknown Nullness . ( reference )


Al echar un vistazo a los detalles de la comprobación de pelusa de Unknown nullness de android.com , vemos que:

Para mejorar el código de referencia de Kotlin , considere agregar información explícita de nulidad aquí con @NonNull o @Nullable .


y en developer.android.com :

Si utiliza Kotlin para hacer referencia a un miembro de nombre no anotado que se define en una clase Java ( por ejemplo, una String ), el compilador no sabe si la String asigna a una String o una String? en Kotlin Esta ambigüedad se representa a través de un tipo de plataforma , String! .


y en kotlinlang.org :

Cualquier referencia en Java puede ser nula , lo que hace que los requisitos de Kotlin de estricta seguridad nula sean poco prácticos para los objetos que provienen de Java . Los tipos de declaraciones Java se tratan especialmente en Kotlin y se denominan tipos de plataforma .


Por lo tanto, cuando anulamos un método Java que sus argumentos no están anotados con anotaciones de nulidad, el IDE agrega un signo anulable ( ? ) Para argumentos en la clase Kotlin . Conduce a evitar lanzar NullPointerException cuando se llama al método en Java al pasar un valor null para uno de los argumentos.

webview.webViewClient = object : WebViewClient() { override fun shouldOverrideUrlLoading( view: WebView, // <- potential to throw NPE before executing the function block! request: WebResourceRequest // <- as well! ): Boolean { return super.shouldOverrideUrlLoading(view, request) } }


En pocas palabras, ¿ NO DEBEMOS eliminarlo ? firmar a partir de argumentos de función, cuando el método reemplazado se define en una clase Java .


La referencia nula es una excepción bastante obvia para todos ahora porque todo comenzó con el desarrollo nativo en C / C ++. La referencia a los objetos en la memoria puede faltar o limpiarse por diferentes razones. Java fue diseñado en forma de esos idiomas nativos , que suponen punteros nulos en todas partes.

Administrar todos los estados mutables se está divirtiendo con miles de microservicios. Esto causa muchas soluciones alternativas para la referencia Nullable. - Objetos Optional - Mock of Null Object - Wrappers alrededor de referencias - Annotations , etc. Y todo esto para evitar cambiar el estado de algún objeto asignado.

Finalmente, Kotlin no es el primero aquí. Scala, con estados inmutables, tenía una excelente experiencia en uso y aplicaciones de soporte. Por lo tanto, responder a esta pregunta y resumir Java fue diseñado de esta manera a partir de su padre C ++, y debe esperar valores nulos en todas partes. Todavía estamos verificando la referencia para nulo, incluso si no está anotado @Nullable , por esta razón. Y de la misma manera, Kotlin maneja el uso de Java, y es por eso que necesita manejar valores nulos en métodos anulados.


Si un método virtual en Java no especifica la nulabilidad de sus parámetros de alguna manera, por ejemplo con las anotaciones @Nullable / @NotNull , puede elegir la nulabilidad de cualquier manera al anular ese método en Kotlin.

¿ Pero cómo debes elegir?

  • Primero, puede consultar la documentación del método y verificar el contrato del método. ¿Especifica que el método se puede llamar con valores nulos, y qué significan estos valores nulos cuando se pasan al método?

    En este caso particular, la página de documento del método WebViewClient.shouldOverrideUrlLoading no dice nada acerca de nulos, por lo que se puede tomar como evidencia de que se supone que sus parámetros no son anulables .

  • En segundo lugar, si aún no está seguro acerca de la nulabilidad después de consultar los documentos, puede considerar qué haría con el valor de parámetro nulo, si recibe uno. Si lo único razonable en esta situación es lanzar una excepción, puede delegar esa verificación al código de verificación de parámetros generado por Kotlin, declarando los parámetros como no anulables.