java - Devo remover a anulabilidade dos métodos substituídos que não são anotados com anuláveis em uma classe herdada




android kotlin (4)

Eles não são especificados como anotação anulável no código Java.

Se isso for verdade, observe que você corre o risco de lançar uma NullPointerException se não for especificada como anotação anulável no código Java e atribuir um valor nulo. portanto, remova a anulabilidade do método substituído, se não for especificado como anotação anulável no código Java.

Para mais detalhes, leia this também kotlinlang.org

Android 3.5.1

Eu estava usando o WebView e notei que, quando eu substituo alguns dos métodos, todos os parâmetros são tipos que permitem valor nulo:

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

O que significa que eu tenho que usar o operador de safe call para usá-los. No entanto, quando observei a classe WebViewClient que substituí o método, elas não são especificadas como anotação nullable no código Java.

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

Então, fico pensando que removo a nulidade do método substituído ou as mantenho?


A fonte desse problema vem da interoperabilidade entre Java e Kotlin . Existem algumas diferenças básicas no nível da linguagem entre Java e Kotlin que causa problemas de interoperabilidade. O Android Studio fornece algumas verificações do Lint para avisá-las, como o Unknown Nullness . ( reference )


Unknown nullness detalhes da verificação de Unknown nullness Lint no android.com , vemos que:

Para melhorar o código de referência do Kotlin , considere adicionar aqui informações de nulidade explícitas com @NonNull ou @Nullable .


e no developer.android.com :

Se você usar o Kotlin para referenciar um membro de nome não anotado, definido em uma classe Java ( por exemplo, uma String ), o compilador não saberá se a String mapeada para uma String ou uma String? em Kotlin . Essa ambiguidade é representada por um tipo de plataforma , String! .


e no kotlinlang.org :

Qualquer referência em Java pode ser nula , o que torna os requisitos de segurança nula rigorosos da Kotlin impraticáveis ​​para objetos provenientes de Java . Os tipos de declarações Java são tratados especialmente no Kotlin e são chamados de tipos de plataforma .


Portanto, quando substituímos um método Java que seus argumentos não são anotados por anotações de nulidade, o IDE adiciona sinal anulável ( ? ) Para argumentos na classe Kotlin . Isso evita o lançamento de NullPointerException quando o método é chamado em Java , passando um valor null para um dos 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)
    }
}


Em poucas palavras, não devemos remover ? assinar a partir de argumentos da função, quando o método substituído é definido em uma classe Java .


Ao contrário do Kotlin, os objetos Java por padrão podem aceitar valores nulos

A anotação @Nullable é usada apenas para operações como analisadores de código (por exemplo, se o parâmetro @Nullable não for tratado dentro do método, será exibido um aviso)

A anotação @NonNull é usada para especificar que o valor recebido não pode / não 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 também: https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html#null-safety


No nível do idioma, isso pode ser generalizado:

Para uma interoperabilidade Java adequada, o código Kotlin deve refletir as anotações do código Java.

O linter reclama apenas da falta de anotações na outra direção, quanto à interoperabilidade do Kotlin.

Veja este artigo recente em Como escrever código Kotlin compatível com Java?





nullable