2017-11-08 14 views
1

私は、JavaコードをライブラリからKotlinに変換しているときに、Javaコードでnullチェックが行われていて、これをどのように変換するのが最適か疑問に思う。Kotlin null from Java

Javaがオブジェクトをnullにするかどうかを制御できないため、私はまだKotlinでif nullチェックが必要ですか?

は、私がこのようにこれを定義する必要があります。..

private lateinit var mCameraDevice: CameraDevice 

、その後、ヌルチェックは必要ありませんか、次のようにバックヌルのJava

から来ることができましたCameraDeviceを考えてみましょう。..

private var mCameraDevice: CameraDevice? = null 

、その後はnullチェックを保つ

if (mCameraDevice != null) { // do something } 

nullを処理する必要はないはずなので、オプション1を使用する必要がありますが、基本的にはすべてのライブラリがJavaなので、nullを処理してオプション2にする必要があるので、KotlinでのNullabilityは私を混乱させます

+1

すべてのタイプが技術的にnull可能であるという理由だけで、実行時にそれらが実際に実行されているわけではありません。あなたの設計がmCameraDeviceがおそらくヌルにならないことを保証している場合(とにかく修正が必要なバグがない限り)、CameraDeviceを使用してください。 nullがmCameraDeviceの有効な値であれば、CameraDevice?を使用します。 CameraDeviceがJavaクラスでもKotlinクラスでも、何も変更されません。 –

+0

JavaライブラリのコードまたはJavaDocがnullでないことが保証されている場合を除き、Java相互運用部分にはnull可能な型を使用する必要があります。 – Naetmul

答えて

1

もしあなたがわからないのであれば、null可能な型をよく使うべきです。なぜなら、レガシーJavaコードが返す可能性は常にnullであるからです。このバージョンは最も安全です。 nullが不可能であることがわかっている場合は、nullを許可しないタイプを使用してください。 docsに書き込まれるように

Javaで任意の参照は、Javaからのオブジェクトの厳密ヌル安全のKotlinの要件は、非現実的になりれ、ヌルであってもよいです。 Java宣言の種類は、Kotlinでは特別に扱われ、プラットフォーム型と呼ばれます。このような型の場合、NULLチェックは緩和されるため、安全性の保証はJavaの場合と同じです。

は、Javaで動作している場合は、あなたがnullになることはありませんだと思うの値は、あなたがNULL可能でないタイプとして彼らと作業する場合、実行時にNullpointerException秒を起こししようとしている戻りました。

のJava:

public class Nullable { 

    public String get(){ 
     return null; 
    } 
} 

Kotlin:

Nullable().get().length //-> NPE 
+0

Javaでnullでないものを設定してからJavaでnullに設定すると、NullPointerExceptionが発生しますか? – Pagrate

+0

はい、それは起こります – s1m0nw1

1
if (mCameraDevice != null) { // do something } 

何がelse場合にはどうするつもりですか?答えが「例外をスローする」場合は、nullを許可しない型を使用するだけで、Kotlinは効果的にそれを行います。それ以外の場合は、null可能な型が妥当です。mCameraDevicevarある場合

また、// do something内Kotlinはそれがnull以外だと仮定することはできません。何かがチェックした後、それを変更することができます!一般的なイディオムがある

mCameraDevice?.let { mCameraDevice -> // do something } 
+0

私はKotlinのヌルの安全性で得られないことの一つは、このシナリオの欠如です。 私はmCameraDeviceのようなことをすればいいですか?またはmCameraDevice?.let私は基本的にこれはmCameraDeviceがnullと等しいではないと言っていますが、nullの場合は何もしません。 コードが黙って失敗し、ユーザが何かが失敗したとは知らないので、私にとっては本当に悪いコーディングのようです。 この点で変更点が変更されている可能性があるため、Kotlinはこの点でスマートキャストできないというエラーを表示するため、elseを使用していないと思われます。 – Pagrate

0

lateinitは本当にあなたが後半に初期化変数、のように聞こえるものだけであるために意味されます。

例えば、アンドロイドでは、アクティビティのコンストラクタを評価していないので、0以外の値でonCreateの値を設定するため、lateinitは、nullでないことがわかっている変数にアクセスしたい場所に便利ですチェック、?の、または!!のです。例えば

lateinitなし

class MainActivity : AppCompatActivity() { 

    private lateinit var field: EditText 

    override fun onCreate(savedInstanceState: Bundle?) { 
     super.onCreate(savedInstanceState) 
     setContentView(R.layout.activity_main) 
     field = findViewById<EditText>(R.id.field) 
    } 

    fun someOtherMethod() { 
     println(field.text) 
    } 

} 

あなたはEditText?としてfieldを宣言して、Kotlinが提供するすべてのヌル安全オプションを使用する必要があります。

Java interopでは、ライブラリメソッドがnullを返すことができる場合は、それをKotlin nullableのように扱い、セーブナビゲーションsomeObject?.someMethodまたはletメソッドなどの安全な方法でアクセスする必要があります。あなたは、特にJavaがヌルCameraDeviceを提供することがありますと言うので、それが目的ではないように、あなたのケースでは、あなたは間違いなくない使用は、このためにlateinitすべき

someObject?.let { it.someMethod } // as also pointed out by Alexey Romanov