Kotlin開発中にふと気になったことを備忘録的にまとめる
はじめに
どうしても警告を無視したい時の最終手段として使用する Suppress アノテーションについて、どんな時なら使用していいのかなどがちょっと気になったので調べてみました
Suppressを使ってもいい状況
そもそもこれを使いたい時というのが「コードは間違っていないけれどなんらかの不具合が発生するかもしれない」「動作が不安定になるかもしれない」「そもそも非推奨の機能」などの警告が発生している場合になります
これらの警告に対して「理解はしているが今の状態が実装として理想的であり、問題ないと判断している」という認識が開発者間で一致した場合に使用するのが Suppress になります
具体的には以下のような警告に対して使用することが考えられます
- 安全だと確信している型キャスト
- 意図的に非推奨の機能を使用する
- オーバーライド時にメソッドの引数名を変えている
- 現時点では使用していない変数などを残す
Suppressの種類と無効化するもの
実際に使用する際はただアノテーションをつけるだけではなく、引数を渡して使用することになります
その際に渡す引数で、何を無効化しているのかを明示することができるので必ずつけましょう
以下、よく使用する引数一覧です
"UNCHECKED_CAST" // 安全ではない型キャスト
"DEPRECATION" // 非推奨のメソッド
"UNUSED_PARAMETER" // 関数内に存在するが一度も使われていない引数
"UNUSED_VARIABLE" // 一度も使われていないローカル変数
"RedundantVisibilityModifier" // 不要、あるいは冗長な可視性修飾語がついている
"PARAMETER_NAME_CHANGED_ON_OVERRIDE" // オーバーライド時に引数名が変更されている
"SpellCheckingInspection" // typo
"MemberVisibilityCanBePrivate" // privateに変更しても問題ないメンバー
"ALL" // 全て(圧倒的に非推奨なので使わない方がいい)
Suppressのスコープ
Suppress を付与する場所によってそのスコープは変わります
スコープの具体例について、Geminiに作成してもらったコードを以下に記述します
// 1. 関数全体で抑制
@Suppress("UNUSED_PARAMETER")
fun someFunction(usedParam: String, unusedParam: String) {
// unusedParam を使わなくても警告が出ない
println(usedParam)
}
// 2. クラス全体で抑制
@Suppress("MemberVisibilityCanBePrivate")
class MyClass {
fun publicApi() { /* ... */ }
fun internalHelper() { /* ... */ } // privateにできる、という警告が出ない
}
// 3. ローカル変数(文)に対して抑制
fun anotherFunction() {
val usedValue = 10
@Suppress("UNUSED_VARIABLE")
val unusedValue = 20 // この変数にだけ適用される
println(usedValue)
}
// 4. 複数指定
@Suppress("DEPRECATION", "UNCHECKED_CAST")
fun complexFunction(list: List<Any>) {
// ...
}
このようになっているので、その警告がどこに対してなのかが明確になるようにつけるようにしましょう
まとめ
警告は可能な限りは解消するべきことであり、無視するというのは本当に最終手段にするべきです
それでもプロジェクトの都合なんかでどうしても Suppress を使用しないといけない時はあるので、そういった時は使い方を間違えないように気をつけましょう