Kotlinを学ぶのにJavaの知識はどのくらい必要なのか

竹端尚人氏(以下、竹端):「Server-Side Kotlinで必要なJavaの知識」というタイトルで始めます。

まず自己紹介からします。竹端と申します。今フリーランスでエンジニアをやっていて、職種としてはバックエンドエンジニア、サーバーサイドKotlinや、Javaなどを主に過去やってきて、そのへんを得意としています。少し前までサイバーエージェントグループで、スマートフォンゲームの開発をやっていましたが、2020年に転職していろいろとやって、2020年12月からフリーランスになりました。

登壇、執筆は、「CEDEC」というゲーム開発者のイベントでサーバーサイドについて登壇したり、『Software Design』という雑誌でもサーバーサイドKotlinについて連載していました。

最近は『Kotlinサーバーサイドプログラミング実践開発』という書籍を発売しました。僕は所属会社がないので「We're Hiring!」はないのですが、よければこの本を買ってもらえたらうれしいなと思います。

サーバーサイドKotlinの本で、サーバーサイドとタイトルに出ていたのは黒べこ本(『Kotlin Webアプリケーション 新しいサーバサイドプログラミング』)ぐらいだと思うので、ここに興味のある方は、ぜひ買ってもらえたらうれしいなと思います。今日はこの本に書いてあることも交えながら、少し話せればと思います。

この書籍の前書きに書いてあるのですが、(Kotlinは)Javaとの相互互換があって、歴史の長い言語であるJavaの資産を使えるところが特徴としてあります。新しい言語でモダンな実装ができて、かつ資産も豊富にあるという、すばらしい言語なのです。

それゆえに、「Javaがわかる人じゃないと難しいのか」とか、「Kotlinを覚えるためにJavaも勉強しなきゃいけないのか」「Javaを先に勉強しなきゃいけないのか」など、心配する声を聞くことがけっこうあります。

そういうのがあるので、今日は実際にKotlinを学ぶのにJavaの知識はどれだけ必要なのかをお話ししたいなと思います。

(今回の参加者は)Kotlinにどういうかたちで関わっている方が多いのかがわからないので、実際にそういう悩みあるよという方は、ぜひ参考にしてもらいたいですし、今もうすでにサーバーサイドKotlinやっているよという方も、改めてこのへんのJavaの知識は必要だよねと整理する意味で、聞いてもらえればなと思います。

Javaの知識があればKotlinを学ぶのは楽になる

まず1個目。Javaの知識は絶対必要なのか。先に結論を言うと、Java自体の知識はなくても学べます。僕が書いているこの書籍でも、Javaとの相互互換について説明しているのが第3章にあるのですが、それ以外ではJavaのコードを一切書いていないです。

Javaの知識があることを前提としなくても、Kotlinを学ぶことは問題ないです。Javaの経験がない場合の学習コストが、他の言語に比べて特別高いかというと、そういうわけではないと思っています。例えば、C#などの他のオブジェクト指向の言語を学ぶのと、そんなに大きくは変わらないと思っています。

ただしJavaを知っていると、学ぶのは圧倒的に楽だとは思います。例えば構文や機能などで、似たものがあります。これは相互互換を謳っている言語ゆえですが、けっこう似たものがあります。

あと、やはりフレームワークやライブラリはJava製のものを活用することがまだまだ多かったりします。世の中にある既存のJavaの資産を活用するのは、Javaを知っていればやりやすいので、より便利に使えるかなあと思います。

なので、Javaを知っていると楽ですが、なくても大丈夫なので、その「必要か?」というところの温度感になります。KotlinをやるためにJavaを先に学ばなくては、みたいなことは、少なくともないなと思っています。

その上で、よく使うJavaの知識をいくつか紹介しようと思います。大きく3つ、こういう話をしようかと思っています。

「オブジェクト指向」「関数型」「フレームワーク」は持っておくとよい知識

まずオブジェクト指向の知識。基本的なクラスやインターフェイス、オブジェクト指向の知識を持っていたり、C#や他のオブジェクト指向の言語をやっていると、理解はしやすいのかなあとは思います。

似たような話で、関数型の知識もあるといいかなと思います。Goなどはクラスがまったくなかったり、どの言語でもそのへんの知識が必要なわけではありませんが、(KotlinやJavaを学ぶには)そこは最低限あったほうが楽かなと思います。本当に広義の意味でのJavaの知識として一応挙げています。

これは大きいところなのですが、フレームワークやライブラリの知識。やはりSpring Bootは無難な選択肢として挙がることがけっこう多かったりします。あと各種ORM、先ほど出ていたjOOQ、MyBatis、Domaもそうなのですが、Java製のものが使われることが多いです。

これは、Exposedが先ほど見たらまだ0.3とかだったので、なかなか1.0にならないこともけっこう大きいのかなとは思っているのですが、Java製のものを使っているところは、けっこう多いです。

テスティングフレームワークも、たぶんJUnit使っているところがまだ多いのかなという感じです。

なので、例えばSpring Bootを知っていた場合は、こういうJavaで作っている時と同じようなアーキテクチャのアプリケーションで実装が理解しやすいです。Spring Bootは、やはりフルスタックのフレームワークなので、けっこうアーキテクチャ全体に影響して、それに引きずられますね。

あと、同じような実装なので、理解しやすくなったり、フレームワークの機能を把握したり、Spring Bootで開発した経験があれば運用ノウハウがあったりするので、そういうところをそのまま生かせるのは大きいかなと思います。

例えばコード例でいうと、(スライドを示し)これはKotlinで書いていますが、この中でJavaを使っていると言えるのは、Spring Bootのアノテーションのところだったり。

先ほど出ていたSpring Securityで、Springフレームワーク側のインターフェイスを実装して、認証認可の処理を実装するのですが、この右側にある実装しているインターフェイスがJavaだったり。

Javaのライブラリを使う場合、例えばuuidライブラリだったり、日付型はけっこうJavaのLocalDateTimeを使うので、時間系のライブラリを呼んでいたり。

Javaのコードは書かないものの、一応このへんはJavaを使うので、知識が必要なものになってくるかなとは思います。

Javaのコードを読んで理解することが必要な場面はある

Javaの言語自体の知識のところでいうと、例えば、フレームワークでJavaのコードを生成する部分や、Javaとの相互互換のために用意されている機能を使う時、その既存のJavaの資産を活用したい場合は、Java自体のコードを読む必要が出てくると思っています。

フレームワークでJavaのコードを生成する部分は、gRPCや各種ORMなどで自動生成するコード、もしくはKotlinに対応していないものもあります。

MyBatisのコードは、けっこうジェネレータがKotlinに対応しているのですが、他がどこまで対応しているのかは把握できていないです。だけど、そういうところでJavaのコードなど、既存のものを呼ばなきゃいけなかったり、自動生成は基本そんなに意識することないのですが、初めて扱う際は、読んでみないと使い方がよくわからなかったりするので、読む必要があるかなと思っています。

gRPCの実装では、このrequestのオブジェクトを作っているところは、Builder、データクラスではなくてBuilderで呼んで、値をセットしています。これも実際生成されたコードが、こういうJavaのコードになっています。自動生成なので書くことはないのですが、必要に応じて読むことはあるかなという感じです。

Javaとの互換機能を使う時でいうと、@JvmStaticとかの各種アノテーションとかSAM変換の部分なのですが、例えば@JvmStaticだとこのアノテーションを付けていますが、これをなんで付けているのかというと、付けないとJavaでCompanionというクラスを介して値にアクセスしなきゃいけないからです。このへんはJavaからどう呼ばれているのかという理解が必要だったりします。

SAM変換も、このJavaのFunctionalInterfaceを呼ぶ時にこういうかたちになっているというのは、理解が必要かと思っています。ただ、今SAM変換は、Kotlin同士でも使えるようになって、そんなにJava独自のものではないので、そんなにかなとは思いますが、一応差分として挙げました。

Javaからどう呼ばれているか、Javaをどう呼んでいるかの理解は、する必要があるかなと思っています。

既存のJavaの資産を活用したい場合は、JavaにしかないOSSを使いたい場合や、組織で持っているJavaの資産を活用したい場合などがありますが、たぶん組織内に有識者がいるためにこういう状況になっていると思うので、この場合はそんなに気にしなくていいかなと思っています。

まとめると、まずJavaを知らなくてもサーバーサイドKotlinを始めることはできます、と言えます。ただし、Javaを知っていると学習コストは圧倒的に下がるので、知っているとだいぶ有利です。

必要レベルで言うと、Javaを書く必要はないけど、多少読んだり理解したりする必要がある場面は存在します。ただ、先ほど話したとおり、自動生成や、読むけど書かない場合もあるので、そんなに怖がらなくてもいいレベルかなと思っています。

なので、怖がらずにみなさんサーバーサイドKotlinをどんどん使っていきましょう、というところで以上になります。ありがとうございました。

言語ではなくアーキテクチャやフレームワークの学びに時間がかかる

司会者:ありがとうございます。それでは質疑応答に移りたいと思います。Companionオブジェクトに@JvmStatic付けなきゃいけないとか、このへんは本当にJavaの知識が必要だなあとは思います。どう付き合うのがいいかなど、何かありますか?

竹端:@JvmStaticは、Javaから呼ぶ場合でいうと、作ったCompanionオブジェクトを呼ぶより、自前で作ったJavaのコードから呼ぶ場合がほとんどだとは思います。ということは、たぶんJavaを作っている会社だと思うので、最後の発言と同じで、有識者がいる状態なのかなとも思ったりはするのですが。

SAM変換は、フレームワークの仕様で、フレームワーク内にあるFunctionalInterfaceを呼ばなきゃいけない時に使ったり、Kotlinだけでやろうとしても、フレームワークを使っている以上、使わざるを得ない時がきたりするので、そういう時は、ボリュームはそんなに大きくはないので、読んで覚えるしかないのかなという気はしています。

まったくゼロはやはり難しいので、最小限に抑えるという意味で、そこらへんだけを覚える点は許容なのかなと思ってはいますね。

司会者:個人的にSAM変換を使っているフレームワークは見たことがないのですが、例えばどういうものがあります?

竹端:検証ライブラリのPredicateとか。フレームワークではないかな。

司会者:ありがとうございます。コメントでは、Javaを書いたことないですが、サーバーサイドKotlinはなんとかやれていますという方もいますね。

竹端:そうですね。フレームワークとかライブラリも、正直中身と使い方だけ理解していれば、(Javaを)読む必要はなかったりします。もちろんしっかりと深く使い込もうとしたら、読んで理解したほうがいいのですが、まず作って、いったんそれなりのものを作るという段階だと、たぶんなんとかなる気はしますね。

僕もバリバリJavaを10年くらいやってからKotlinをやった人なので、感覚が本当に正しいのかは、若干自信がないのですが、実際にやっている方がいるんですね。

前に、「Twitter」でも聞いたことがあるのですが、結局、アプリケーションのアーキテクチャなど、そのへんを学ぶのに時間がかかるだけで、言語自体が特別難しいということはないという印象ですね。

司会者:そうですね。フレームワークを学ぶのには、どの言語でもそうですが時間かかるのかな、というのはありますね。

竹端:それで言うと、Springが難しいですね。

司会者:Springは難しいですね(笑)。あれは、アノテーションから何から覚えることが多すぎて。

Kotlin導入のためにわざわざJavaの教育をやる必要はない

司会者:1つ重めの質問が来ているのですが、これはいかがですか。「PHPerの職場にサーバーサイドKotlinを導入したいと考えているのですが、ある程度Javaも教育したほうがよいでしょうか。」

竹端:Javaの教育という意味では、時間を取らなくてもいいかなとは思っていますね。例えばSpring Bootも、もはやKotlinのフレームワークとして覚えるぐらいの感じで。単純にKotlinから始めちゃってもいいとは思っています。Javaを使うところで必要があれば、そこを覚えるくらいでいいかと。

KotlinとJavaの基礎的な部分の構文はそんなに変わらないし、むしろKotlinのほうが便利に書けたりするので、Javaの基礎構文をきちんやるに越したことはないけど、二重にそこの時間とってやらなくてもいいかなとは思いますね。

司会者:竹端さんは、最近の最新版のJavaは使われたことがありますか?

竹端:うーん、11ならあります。安定版までですね。

司会者:15とかだと、けっこういろいろな機能が入っていたりするので、そことの比較で、Java15を勉強してからKotlinはどうなのかな、と思ったりはします。

竹端:そうですね。ただ、けっこう機能が増えていますが、Kotlinだともともとある機能だったりはするんですよね。

かつ、エクスペリメンタルの場合の機能もけっこうあるので、そこを覚えても、結局Kotlinで普通に書けるのだったら、最初からKotlinでもいいかなという気はしちゃいますね。

司会者:うん。(コメントを見ながら)Javaの言語仕様はKotlinの下位互換(笑)、まあまあ。

竹端:ああ(笑)。それはKotlinがJavaの上位互換として作っているところもあるから、そうですね。最初に書いたとおり、前提知識としてJavaがないとKotlinができないということはまったくないので、二重にやらなくてもいいとは思っています。知っていたら楽だよ、 というぐらいな感じです。

司会者:(僕もLLからServerSide kotlinですが、ORMの文化の違いが一番大きな壁でした という質問を見て)LLからサーバーサイドKotlin、ORMは確かにしていますね。

竹端:そこはそうですね。たぶんKotlinに限らずな気はしますね。難しいところは、言語自体というより、やはりそういうところの話になってくるのですね。それを言うと、PHPからJavaに移るのも普通に大変だったりしますからね(笑)。

司会者:PHPからJavaは大変ですよね。

竹端:結局はそれと同じだとは思います。なので、Kotlinにいくにしても、Javaを導入するのと同じ痛みはたぶんある程度あるんじゃないのかな。

司会者:痛みを乗り越えてPHPからKotlinに移るのは、どうお考えですか。

竹端:僕は、型がないと安心して生きていけない人種なので。PHPも型が一応ありますが価値はあるとは思っていて、そこの状況次第なのですが。

もともとLL言語は、パッと作ってパッと動かしてやるのが早いから、中小規模のスピードを早くして開発したい時に有効、みたいなのはあったりしたのですが、今はどの規模の会社でもCIを回したり、しっかりとテストを書いて実行してやっていると考えると、そこらへんの開発スピードのメリットは薄れて、なくなってきているのかなって気がします。

そういう意味では、こういう静的型付け言語でモダンなものに移行するのは有効な気がしていますね。

司会者:時間になりましたので終わります。ありがとうございました。