飴屋

Kotlin/Javaから変換

過去に書いたjavaファイルをAndroid Studio ではKotlinファイルに変換できるそうです。Projectパネルでjavaファイルの上で右クリックすると「Covert Java file to Kotlin file」というメニューが出てくるので、そこから処理を開始できました。変換後のファイルはちょっとエラーを起こしちゃってる部分もありましたが、ちょっとした修正で直ってくれたのでこれは使えそうです。エラーはそれでいいとしてWarningがずらずらっと増えちゃうのがちょっと見た目が悪いです。気になる・・・。あと本当に元のJavaと同じように動くのか不安もぬぐえません。結局、生成されたKotlinファイルを叩き台にして、よりKotlin風に書き直していくことになりそうです。ちょこちょこWarningを消しながらよくある類型をここにメモって行こうと思います。

Name shadowed

引数に変更を反映する場合、

fun goNiSuru(h: Int) {
  var h = h
  h = 5
}

一度同名の別の変数に再割り当てするようにコードが書かれてました。これがシャドーイングってやつですかね。引数h がval的にふるまうので、同名のvar的変数に割り当てなおしていると。引数を変数として操作しないような書き方に直せることがほとんどだったので、がんばって書き直しています。setXXXXみたいなメソッドで頻発してたのでKotlinのsetterっぽく書き直すのがいいんだろうな、って思いました。

@JvmField

@JvmField っていうアノテーションがプロパティについてました。これがついてると、Kotlinのgetter / setter を介さないで直接プロパティ値にアクセスできるらしいです。一つ上にもでてきたgetXXXX / setXXXX みたいなメソッドを書いてた時代のコードなのでこんなアノテーションも必要なんだろうなー。Kotlinのgetter / setter に書き換えてきれいにする場合は、クラス利用時のコードも併せてリファクタリングする必要があるので、もうちょっと全体を見渡してから手を付けたい。

Redundant visibility modifier

冗長な可視性修飾子という指摘で、自動変換の生成コードのclassのconstructorについてたinternal修飾子が要らないぞってことらしい。要らないからconstructorごと消して終了。

Function "xxxx" is never used

使わないのに残しておいた関数を指摘されました。Kotlin化と関係なくJava時代から消しておけって話ですね。ライブラリ的なものだったら、きっとWarningを抑制するアノテーションがあるんだろうな。

Remove empty constructor body

中身のないconstructerを要らないと指摘されました。要らないので消しました。

internal constructor() {}

↑これが↓こう。{}を消すだけ灰色のwarningなので修正優先度は低いようです。

internal constructor()

Type mismatch: inferred type is xxxx? but xxxx was expected

?のついたNullableな型を引数に渡しているに指摘されました。Javaのコードでは初期値にnullを指定しておいた変数が、Kotlin変換によってNullableになっていたようです。nullを入れることなんてないので、Non Nullableな型に変更しました。

'String' concatenation can be converted to a template

文字列を+演算子で連結するのは効率悪いから、Kotlinのテンプレートを使えとの指摘です。言われるがままに書き換えてもらって終わりです。

None of the following functions can be called with the arguments supplied

MenuItem.setIcon(null) したときに出たエラー。nullを引数にするないうことか?
MenuItem.icon = null という書式にsetterを改めたらOKでした。

Condition '*** == null' is always 'false'

null値かどうかチェックする処理がKotlin化で不要になりました。ここでは常にfalseなので条件分岐で不要な部分をガッツリ捨てました。

Private property name '***' should not contain underscores in the middle or the end

プロパティ名にアンダースコアを使うのは命名規則的に勧められないよ、という指摘。プロパティ名だったら改名すればいいだけですが、今回は定数のつもりでいたものが内部変数として書き換えられていたのでconstをつけて、companion objectに移動しました。・・・companion objectってなんだっけ?staticがKotlinにはないので、クラスの静的な要素を書く場所がcompanion object って感じかな。

class MainActivity : AppCompatActivity() {
    companion object {
        const val HOGE_HOGE = 1
    }
}

改名する場合はRefactor - Rename コマンド(Shift + F6)が楽でしたが、↓別のエラーにつながったこともありました。

Accidental override: The following declarations have the same JVM signature

どうもプロパティのgetterかsetterが何かと競合したらしいです。わかんないからプロパティ名の方を変えて回避しました。(scaleXとかで発生しました。)

Redundant Companion reference

↑companion object に定数を送った時に定数の前に「Companion.」をくっつけてくれたけどこれが不要らしい。削って対応しました。

Can be joined with assignment

宣言と初期値指定が複数行に分かれていたら、単行でできるよと教えてくれる模様。単行にしてもらった。ifが式として評価されるようになったので、こういう指摘がくることもあるのか。なるほど。

Explicitly given type is redundant here

型の指定を明示する必要はないよ、という指摘。必要ないなら削ってもらいましょう。

Smart cast to '***!' is impossible, because '+++' is a mutable property that could have been changed by this time

書き換え可能なプロパティは中身がnullに代わっているかもしれないから、無条件に「!」付きに型キャストできないよ、という指摘。変数の後に「?」をつけてnullではないと保証してあげるのが簡単だったけど、そもそもnullを許容しないプロパティにできるのならそっちがいいのかな。

Use of setter method instead of property access syntax

setXXXみたいなメソッドを使わないでプロパティを直接変更する書式にすればいいじゃん、という指摘。言われるがままにする。setXXXみたいな書き方がKotlinでは一般的ではないのか。

Parameter '***' is never used, could be renamed to _

クリックリスナーでリスナーにビューが渡されてるのに使ってないよね、使わないなら変数名をアンダースコア(_)にしちゃえば?、という指摘。言われたとおりにアンダースコアに変えたら↓次の指摘が飛んできた。

Redundant lambda arrow

ラムダに引数渡さないならアロー演算子は要らないね、という指摘。引数全部使わないならアンダースコアなんかにせず、ガっと全部消してしまえ、ということか。

Property must be initialized or be abstract

プロパティには初期値を入れておけ、という指摘。あとで適切に書き換えられるのなら、適当に値を突っ込んでおけばいいのだろうか。事前に初期値が決定できるなら、それを入れておけばよいですね。

CharSequence.split

文字列を分割するとき、splitメソッドに正規表現を渡していた部分をうまくKotlin風に変換されてなかったので手動で修正しました。

// 正規表現のまま分割しようとしてた
val cells = line.split("[\\t,]")

// TAB文字とカンマで分割したかったので、別個に指定するように変更
val cells = line.split("\t", ",")

// それか正規表現であることを明示した
val cells = line.split(Regex("[\\t,]"))

なお、matches はRegexとちゃんと明示してくれていた。

This declaration overrides deprecated member but not marked as deprecated itself. This deprecation won't be inherited in future releases. Please add @Deprecated annotation or suppress.

古いJavaコードにはdeprecatedなメソッドもいっぱいです。とりあえず@Deprecated アノテーションをつけてお茶を濁しておきました。いや、やっぱり思い切って消しました。ちなみにonBackPressedです。

'on***' overrides nothing

何かの実装箇所でoverrideな関数が実装されていないよってことらしいけど、Javaの時点では実装されていたはずなのでよく見ると関数の引数に?(Nullable)がついてたせいで実装要件と微妙に一致しなかったみたいです。?を取っ払ったら問題が解消しました。

Switch statement on an `int` with known associated constant missing case `***`, `+++`, `
~`

エラーコードを表す定数をwhen式で場合分けしたときにでた警告です。いくつか指定されてなかったエラーコードがあったようで、抜けを埋めるか、あるいはelse条件を追加すると解消しました。

Last-Modified