---
title: "Kotlin と Android の java.lang.NullPointerException をメッセージから解決する"
description: "Kotlin の java.lang.NullPointerException は、!!、非 null 型に入れた Java の値、null のキャスト、Java 側からの呼び出しで起きます。JDK 17 で 6 通りの方法で発生させ、メッセージごとの解決方法を示します。"
canonical: "https://logbrew.co/ja/errors/nullpointerexception"
last_updated: "2026-11-10"
---

# Kotlin と Android の java.lang.NullPointerException をメッセージから解決する

Kotlin の `java.lang.NullPointerException` は、`!!`、非 null 型に入れた Java の値、`null` のキャスト、Java 側からの呼び出しで起きます。JDK 17 で 6 通りの方法で発生させ、メッセージごとの解決方法を示します。

2026年11月10日 に Kotlin 2.4.0、OpenJDK 17.0.18、logbrew-kotlin 0.2.3 で検証

執筆 [Furkan Erday](https://github.com/furkanerday). Furkan Erday は LogBrew の創業者です。毎日 Claude Code と Codex を使って LogBrew を開発しています。

Canonical: https://logbrew.co/ja/errors/nullpointerexception

## `NullPointerException` のメッセージが示すもの

| コードがしたこと | `NullPointerException` | メッセージが原因を示す |
| --- | --- | --- |
| null の値に `order!!` | はい | メッセージなし |
| Java の値を非 null の `val` に代入 | はい | `getProperty(...) must not be null` |
| `null as String` | はい | `null cannot be cast to non-null type` |
| Java から Kotlin の引数に `null` | はい | `Parameter specified as non-null is null` |
| Java で `null` にメソッド呼び出し | はい | `Cannot invoke "String.length()"` |
| セット前に `lateinit` を読み取り | `UninitializedPropertyAccessException` | `lateinit property keg has not been initialized` |

JDK 17 と Kotlin 2.4 で 6 回実行。1 列目のジョッキがいっぱいなら `NullPointerException` が発生し、2 列目がいっぱいならそのメッセージが原因を示しています。

## メッセージを読み、次に最初のフレームを見る

### 自分のコードの行を見つける

自分のパッケージの最初のスタックフレームに、ファイルと行が書かれています。トレースに `Caused by:` のセクションがあれば、その下のフレームを先に読んでください。メッセージを見れば、下の 5 つのケースのどれに当たるか分かります。

### null の値に `!!` を使うとメッセージなし

`!!` はメッセージなしの `NullPointerException` をスローするため、コロンの後にメッセージを出力するロガーでは `java.lang.NullPointerException: null` と表示されます。最初のフレームの行に `!!` があります。

```bash
val order: String? = null
order!!.length
```

出力

```text
java.lang.NullPointerException
	at NpeKt.main$lambda$0(Npe.kt:27)
```

### Java の値を非 null 型に入れたときの `must not be null`

Java のメソッドはプラットフォーム型を返し、Kotlin は非 null の変数に入れたときだけ検査します。`getProperty(...)` は、`null` を返した呼び出しの名前です。

```bash
val beer: String = System.getProperty("taproom.beer")
```

出力

```text
java.lang.NullPointerException: getProperty(...) must not be null
	at NpeKt.main$lambda$1(Npe.kt:30)
```

### Java から Kotlin に `null` を渡したときの `Parameter specified as non-null is null`

Kotlin は公開関数が呼ばれたときに非 null の各引数を検査するため、Java からの `null` は関数の最初の行で失敗します。メッセージには関数と引数の名前が入ります。

```bash
// Kotlin
fun greet(name: String): Int = name.length

// Java
NpeKt.greet(null);
```

出力

```text
java.lang.NullPointerException: Parameter specified as non-null is null: method NpeKt.greet, parameter name
	at NpeKt.greet(Npe.kt)
```

### `null` をキャストしたときの `null cannot be cast to non-null type`

`null` に `as String` を使うとスローされます。`as? String` なら代わりに `null` を返し、私たちのテストでも例外なしでそうなりました。

```bash
val value: Any? = null
value as String
```

出力

```text
java.lang.NullPointerException: null cannot be cast to non-null type kotlin.String
	at NpeKt.main$lambda$2(Npe.kt:35)
```

### Java コードで `null` にメソッドを呼んだときの `Cannot invoke`

JDK 15 以降、Java はメソッドと変数の名前を示します。`<local0>` は、クラスが `-g` なしでコンパイルされ、変数名が失われたという意味です。`javac -g` でコンパイルすると変数名が見えます。Android では、ランタイムが代わりに `Attempt to invoke virtual method ... on a null object reference` と書き出します。

```bash
String beer = null;
beer.length();
```

出力

```text
java.lang.NullPointerException: Cannot invoke "String.length()" because "<local0>" is null
	at Caller.lengthOfNull(Caller.java:10)
```

## Kotlin と Android で解決する

### `!!` を代替値か名前付きの失敗に置き換える

`?:` はデフォルト値を返すか、関数を抜けます。メッセージ付きの `requireNotNull()` はすぐに失敗して何が欠けていたかを伝えるので、最初のフレームとメッセージの両方が原因を指します。

```bash
val order = orders[id] ?: return
val keg = requireNotNull(taps[id]) { "keg is not set for tap $id" }
```

出力

```text
java.lang.IllegalArgumentException: keg is not set for tap 3
	at NpeKt.main$lambda$6(Npe.kt:48)
```

### Java との境界では型を nullable で宣言する

Java からの値に nullable 型を付けると、コンパイラが使う前に `null` の処理を求めます。自分の Java コードに `@Nullable` と `@NonNull` を付ければ、Kotlin にはプラットフォーム型ではなく実際の型が見えます。

```bash
val beer: String? = System.getProperty("taproom.beer")
val name = beer ?: "house ale"
```

### JSON パーサーは後ではなくパース時に失敗させる

リフレクションでオブジェクトを組み立てるパーサーは、非 null の Kotlin プロパティに `null` を入れることがあり、例外はパースから離れた場所で現れます。square/moshi#143 が 2016年にこれを報告しました。2018年1月に、欠けた非 null フィールドを拒否する Kotlin アダプターを使うという回答で閉じられました。

### `lateinit` は最初に使う前にセットする値だけに使う

セット前に読み取った `lateinit` プロパティは、`NullPointerException` ではなく `UninitializedPropertyAccessException` をスローします。先に `::keg.isInitialized` を確認するか、値を計算できるなら `by lazy` を使ってください。

```bash
class Taproom {
    lateinit var keg: String
}

Taproom().keg.length
```

出力

```text
kotlin.UninitializedPropertyAccessException: lateinit property keg has not been initialized
	at Taproom.getKeg(Npe.kt:6)
```

### 例外をスタック付きで LogBrew に送る

Kotlin SDK の `captureThrowable()` は、例外の型、スタックフレーム、原因のチェーンを送信し、LogBrew は繰り返しを 1 件の問題にまとめます。`includeMessage = true` を渡さない限り、メッセージは含まれません。アプリでは、記録用トランスポートの代わりに `HttpTransport()` を `flush()` に渡してください。

```bash
import co.logbrew.sdk.LogBrewAndroid
import co.logbrew.sdk.LogBrewClient
import co.logbrew.sdk.RecordingTransport

val transport = RecordingTransport.alwaysAccept()
val client = LogBrewClient.create(apiKey = System.getenv("LOGBREW_API_KEY"), sdkName = "logbrew-kotlin", sdkVersion = "0.2.3")
try {
    val beer: String = System.getProperty("taproom.beer")
    beer.length
} catch (e: NullPointerException) {
    LogBrewAndroid.captureThrowable(client, "evt_npe_1", "2026-11-10T09:00:00Z", e)
}
println(client.flush(transport))
```

出力

```text
TransportResponse(statusCode=202, attempts=1)
```

## 実際に試して確認したこと

OpenJDK 17.0.18 上の Kotlin 2.4.0 で Kotlin ファイル 1 つと Java ファイル 1 つをコンパイルし、6 通りの方法で例外を発生させました。4 つは Kotlin コードからで、`!!`、非 null の `val` に入れた Java の値、`null` への `as String`、Java が Kotlin の引数に渡した `null` です。5 つ目は Java での `null` へのメソッド呼び出しでした。6 つ目の `lateinit` の読み取りは、そもそも `NullPointerException` ではありませんでした。

メッセージがなかったのは `!!` のケースだけでした。残りの 4 つは、呼び出し、引数、型、メソッドのいずれかの名前を示しました。Java のメッセージでは、`-g` なしでコンパイルしたため変数が `<local0>` と表示されました。

メッセージ付きの `requireNotNull()` は、書いたその行で `IllegalArgumentException: keg is not set for tap 3` をスローしました。`as? String` は例外なしで `null` を返しました。

## Kotlin でも NullPointerException が発生する理由

Kotlin コンパイラは nullable 型への呼び出しを拒否するため、Kotlin コードが `NullPointerException` をスローするのは、自分でそう求めた場所だけです。null 安全のドキュメントは、`!!`、明示的な `throw`、初期化されていない `this`、Java との相互運用だけを原因として挙げています。`as` による `null` のキャストでも発生することは、私たちのテストが示しています。

Java からの値はプラットフォーム型で、コンパイラのメッセージでは `String!` と書かれます。`String` にも `String?` にも入れられます。`String` に入れると Kotlin は代入時に検査して `must not be null` をスローし、私たちの 2 回目のテストはそこで失敗しました。

JEP 358 は JDK 14 で `Cannot invoke ... because ... is null` というメッセージを JVM に追加し、JDK 15 でデフォルトで有効になりました。Android のランタイムは独自のテキストを書き出します。google/gson#1778 には、Android アプリからの `Attempt to invoke virtual method 'int java.lang.Object.hashCode()' on a null object reference` が載っています。

## LogBrew が記録する内容

`captureThrowable()` は、`NullPointerException` というタイトルの問題を 1 件、レベル `error` で送信しました。`exception.type` は `NullPointerException`、メカニズムは `android.exception`、`handled: true` でした。原因のチェーンには `java.lang.NullPointerException` のエントリが 1 件あり、7 つのスタックフレームにはそれぞれファイル、行、関数、モジュールが付いていました。最初のフレームは `Npe.kt` の 58 行目の `main` でした。

メッセージは含まれず、チェーンのエントリは `messageState: "redacted"` でした。`includeMessage = true` を付けると、問題のメッセージは `getProperty(...) must not be null` になりました。`includeStackTrace = true` を付けると、メタデータのフィールド `throwableStackTrace` にメッセージなしのトレースのテキストが入りました。

`flush()` は記録用トランスポート経由で `statusCode=202, attempts=1` を返しました。`HttpTransport()` を渡せば、同じ本文が LogBrew に送られます。

## よくある質問

### NullPointerException とは何ですか？

メソッド呼び出し、フィールドの読み取り、配列のインデックス、アンボクシングで、コードが `null` を保持する参照を使ったときに JVM がスローする例外です。`RuntimeException` を継承しているため、`throws` 節には書かれません。

### null 安全があるのに、Kotlin で NullPointerException が発生するのはなぜですか？

Kotlin がコンパイル時に null 可能性を検査するのは Kotlin の型だけです。`!!`、`null` への `as`、非 null 型に入れた Java の値、`null` を渡す Java 側の呼び出しは、すべて実行時にスローします。それぞれのメッセージは上に挙げたとおりです。

### `java.lang.NullPointerException: null` とはどういう意味ですか？

例外にメッセージがないという意味です。コロンの後にメッセージを出力するコードは、そこに `null` と書きます。Kotlin では `!!` がまさにこの例外をスローするので、最初のフレームの行で `!!` を探してください。

### Parameter specified as non-null is null とはどういう意味ですか？

Java かリフレクションが、引数が非 null の Kotlin 関数に `null` を渡したという意味です。メッセージには関数と引数の名前が入ります。引数を nullable にするか、呼び出し側で `null` を止めてください。

### Android で NullPointerException を解決するには？

`Caused by:` の下にある自分のパッケージのフレームを読み、メッセージを上のケースと照らし合わせてください。Android ではランタイムが `Attempt to invoke virtual method ... on a null object reference` と書き出し、そこに示されたメソッドが `null` への呼び出しです。

### NullPointerException は検査例外ですか？

いいえ。`RuntimeException` を継承しているため、コンパイラは catch を求めません。catch するのではなく原因を直してください。メソッド呼び出しに届いた `null` は、その手前のコードのバグです。

## すべての NullPointerException をスタック付きで見る

LogBrew の Kotlin SDK は、各例外を型、スタックフレーム、原因のチェーン付きで送信し、LogBrew は繰り返しを 1 件の問題にまとめます。余裕のある無料プランで始められます。クレジットカードは不要です。

[無料で始める](https://logbrew.co/ja)

## 出典

- [Kotlin docs, Null safety](https://kotlinlang.org/docs/null-safety.html)
- [Kotlin docs, Null-safety and platform types](https://kotlinlang.org/docs/java-interop.html#null-safety-and-platform-types)
- [JEP 358, Helpful NullPointerExceptions](https://openjdk.org/jeps/358)
- [square/moshi#143](https://github.com/square/moshi/issues/143)
- [google/gson#1778](https://github.com/google/gson/issues/1778)

## ほかのエラーの解決方法

- [メッセージ、ファイル、行を隠す Script error を解決する](https://logbrew.co/ja/errors/script-error)
- [Failed to fetch エラーを解決し、3 つの原因を見分ける](https://logbrew.co/ja/errors/failed-to-fetch)
- [再現したエラーとそれぞれの解決方法](https://logbrew.co/ja/errors)
