Предоставить Kotlin предупреждение о назначении гибкого/платформенного типа для непустого типа?

При вызове функции Notable-annotated Java от Kotlin мы получаем возвращаемые значения с гибким типом, обозначенные восклицательными знаками, например. String!.

Kotlin молча разрешает назначать эти гибкие значения нормальному непустому типу, например. String, что может вызвать NullPointerExceptions во время выполнения.

Я бы предпочел получить предупреждения или ошибки компилятора для таких назначений. Альтернативно, рассматривайте типы платформ как эквивалентные типам NULL (например, String?).

В качестве примера, с этим кодом Java:

import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

public class NullTest {

    private String maybe() {
        if (SystemClock.elapsedRealtimeNanos() % 2 == 0) {
            return null;
        }
        return "ok";
    }

    public String annotatedNothing()            { return maybe(); }
    @Nullable public String annotatedNullable() { return maybe(); }
    @NonNull  public String annotatedNonNull()  { return "ok"; }

}

... и следующий код Котлина, я хотел бы получить ошибки в двух новых строках (см. комментарии):

fun testnulls() {
    val obj = NullTest()

    val nullExact: String  = obj.annotatedNullable() // already gives an error
    val nullMaybe: String? = obj.annotatedNullable()
    val nullInfer          = obj.annotatedNullable()

    val okayExact: String  = obj.annotatedNonNull()
    val okayMaybe: String? = obj.annotatedNonNull()
    val okayInfer          = obj.annotatedNonNull()

    val bareExact: String  = obj.annotatedNothing() // I want a compiler error here
    val bareMaybe: String? = obj.annotatedNothing()
    val bareInfer          = obj.annotatedNothing()

    print("length " + nullExact.length)
    print("length " + nullMaybe.length) // already gives an error
    print("length " + nullInfer.length) // already gives an error

    print("length " + okayExact.length)
    print("length " + okayMaybe.length) // already gives an error
    print("length " + okayInfer.length)

    print("length " + bareExact.length)
    print("length " + bareMaybe.length) // already gives an error
    print("length " + bareInfer.length) // I want a compiler error here
}

Дело в том, что это заставит меня добавить нулевые проверки или !!, убедившись, что я, по крайней мере, должен быть явным.

Возможно ли это?

В комментариях этого сообщения 2014 JetBrains, когда они представили платформы/гибкие типы, похоже, что они планировали добавить опцию чтобы предупредить об этих ситуациях, но я не смог найти дополнительную информацию об этом.

Ответы

Ответ 1

Документация Kotlin описывает этот точный случай:

Любая ссылка в Java может быть нулевой, что делает требования Котлина строгой нулевой безопасности непрактично для объектов, поступающих с Java. Типы деклараций Java обрабатываются специально в Котлине и называются типы платформ. Нулевые проверки ослаблены для таких типов, так что безопасность гарантии для них такие же, как в Java

К сожалению, это означает, что во время компиляции невозможно выпустить предупреждение. Серебряная подкладка состоит в том, что Котлин, по крайней мере, предотвратит распространение пустоты во время выполнения.

Когда мы вызываем методы для переменных типов платформ, Котлин не выдавать ошибки с ошибкой при компиляции, но вызов может из-за исключения с нулевым указателем или утверждения, что Kotlin генерирует, чтобы предотвратить распространение нулей

Если я не контролирую исходный код используемой библиотеки Java, я обрабатываю все результаты как потенциально нулевые, если только не очевидно, что они не являются.

Ответ 2

Да, возможно получать предупреждения и/или ошибки компилятора для любых назначений из Java-методов с сильным допущением, что если у метода нет аннотации @NotNull, это @Nullable.

Как?:) Вам нужно будет написать свой собственный плагин Custom Custom Inspection.

Вот некоторые полезные ссылки для тех, кто достаточно опытен, чтобы создать этот настраиваемый плагин инспекции (возможно, я был бы среди его благодарных пользователей):


Если вы знакомый и опытный разработчик плагинов Idea, это может не потребовать много времени. В противном случае я не думаю, что результат, который вы собираетесь достичь, действительно стоит того времени, которое вам придется потратить.

Мне нравится ваша идея, но AFAIK на ранних стадиях разработки kotlin была предпринята попытка реализовать как полную проверку безопасности по нулевой мере, и оказалось, что было слишком много потенциально небезопасных назначений.

p.s. Если вы, наконец, создадите этот плагин осмотра, пожалуйста, дайте мне знать. Я лично попытался это сделать, но в моем случае я сначала узнаю о плагинах Idea.

Ответ 3

для непустых строк -

check isEmpty(). Вы не сможете передавать непустые строки в этом методе. Таким образом, он безопасен по типу.

для нулевых строк -

вы можете проверить значение null в условии if.