エンジニアHubPowered by エン転職

若手Webエンジニアのための情報メディア

Javaなら「この書き方がベスト」と信じて書ける - きしだなおきに聞く、Javaのこれまでとこれから

Javaは1995年に誕生し、数多くのコミュニティや企業の影響を色濃く受けてきました。では、黎明期から現代に至るまで、Javaはどのように進化し、生態系を変化させてきたのでしょうか。Javaのスペシャリストとして知られる、きしだなおきさんに聞きました。

Javaきしだなおきさんメインカット

1995年に誕生した、オブジェクト指向プログラミング言語・Java。この言語の歴史は、数多くのコミュニティや企業の影響を色濃く受けてきました。

例えば、OracleによるSun Microsystemsの買収後、Javaのリリースサイクルは大きく変化しました。また日本においては、JavaカンファレンスやSeasarプロジェクト、日本Javaユーザグループといったコミュニティの存在が、Javaの普及・発展に大きな影響を及ぼしたことは間違いないでしょう。

では、黎明期から現代に至るまで、Javaはどのように進化し、生態系を変化させてきたのでしょうか。Javaのスペシャリストとして知られるLINE Fukuoka株式会社のきしだなおき@kisさんに、その歴史を伺いました。

Strutsの斬新さは、オープンソースであったこと

——きしださんは、Javaのスペシャリストとして知られています。業務のなかで、Javaに触れるようになったのはいつ頃ですか?

きしだ 学生時代から趣味で触れてはいましたが、業務という意味では2001年からですね。もともと、友人がプログラミングを教えるアルバイトをしていたんですが、彼が就職を決めてアルバイトを辞めまして。代わりに僕がそこでJavaを教えることになったんです。

当時はまだ、見よう見まねで書いていて、詳細な言語仕様はよく分かっていませんでした。人に教えながら、テキストを書きながら、少しずつ仕様を覚えていき、同時に開発業務でもJavaを使うようになっていきました。

きしだなおきさん正面
きしだなおきさん:LINE Fukuokaに社員として勤務。Javaスペシャリストとして知られる。小学5年生の頃にMSX-BASICに触れて以来、学生時代にC言語やZ80アセンブラ、C++、Visual Basicなど数多くのプログラミング言語を学ぶ。2000年にフリーランスエンジニアとして活動開始。2001年にプログラミングを教えるアルバイトを始めたことをきっかけに、Javaの仕様について深く学ぶようになる。2015年より現職。主な著書に『創るJava』など。ブログ:『きしだのHatena

——それ以前にも、プログラミング言語には触れられていたのですか?

きしだ 学生時代から、いろいろなプログラミング言語に触れていました。小学5年生の頃にMSX-BASICを書くことからスタートして、Z80アセンブラをやって、C言語をやって……。学生時代にはアルバイトでC++やVisual Basicを書いて。2000年にフリーランスになってからは、最初の仕事としてPHPを書いています。

——いま名前が挙がった言語とJavaは、さまざまな面で違いがあったかと思います。Javaという言語に、どのような印象を抱きましたか?

きしだ まじめな言語だなあ、と感じましたね。例えば、C++は演算子オーバーロードがあるのでプログラマに自由度の高い書き方を許していますが、Javaではplusなどのメソッドを定義する必要があるし、Visual Basicだと言語仕様にわりと曖昧な部分がありますが、Javaは仕様がはっきり決まっている。それに、PHPやVisual Basicは型における緩さがあります。一方のJavaは、良くも悪くも動きがかっちり決められていますよね。記述が冗長になっても動きがはっきりするようになっている。

——2000年代の前半には、有名なJavaフレームワーク・ライブラリが数多く登場しています。例えばApache Struts(以下、Struts)がかなり有名ですが、なぜStrutsは当時、多くのユーザーの評価を得たのでしょうか?

きしだ Strutsが斬新だったのは、オープンソースのフレームワークだったということです。というのも、Strutsが登場するまでJavaのフレームワークは“有料”なのが当たり前でした。例えばJavaを用いたシステム構築を可能にしてくれるミドルウェア製品として、日立製作所が提供していたCosminexusがありますが、エンタープライズエディションを使用するには何十万円も支払う必要がありました。

——現代のように、「ライブラリ・フレームワークは無料で使えるのが当たり前」という時代ではなかったのですね。その状況下で、無料で使えて、かつ便利なフレームワークが登場したのは衝撃的だったと。

きしだ ただ、僕は個人的にそれほどStrutsが好きではなかったですけどね(笑)。XMLを山ほど書かなければいけないなど面倒な作業が多くて、使いにくかったんです。設計がナンセンスだと思っていました。だから僕は、Strutsの不便な部分を解消するために、独自に機能拡張したフレームワークを使っていました。

——どのような方法で機能拡張を行っていたのですか?

きしだ 2004年に、J2SE 5.0でアノテーションという文法が出たんですね。アノテーションを付与することで、Javaでメタプログラミングが容易になりました。当時の僕は「アノテーションを活用すれば、XMLをたくさん書かなくていいようにStrutsを拡張できる」と考えて、アノテーションを使い倒してStrutsをカスタマイズしていました。僕はこのフレームワークを“無設定Struts”と呼んでいました(笑)。

——無設定Strutsですか(笑)。

きしだ 実はこの独自フレームワークは、SeasarプロジェクトでメンテナンスされていたS2Strutsの元ネタになっているんです。というのも、Seasarファウンデーションのコミッターの1人である木村 聡さんが無設定Strutsを見つけてインスピレーションを得たことが、S2Strutsの誕生に繋がっているからです。

日本のOSSコミュニティに大きな影響を与えた、Seasarプロジェクト

——驚きました。S2Strutsの誕生にきしださんのコードが大きく影響していたとは。プログラミング言語やフレームワーク・ライブラリの設計や機能は、誰かが書いたコードの影響を受けて変わるものなのですね。

きしだ そうです。だからこそ、言語やフレームワーク・ライブラリが発展するうえで、コミュニティの存在は非常に大きいと思っています。例えば日本では、Javaの黎明期にJavaカンファレンスやJavaコンソーシアムなどのユーザーコミュニティが存在しました。その後、2000年代後半にSeasarプロジェクト日本Javaユーザグループが発足しました。

これらのコミュニティは、日本におけるJavaの発展に大きく影響しています。特にSeasarプロジェクトの存在は、日本におけるオープンソースの歴史上、かなり大きな意味を持っているのではないかと思います。当時、気の利いたエンジニアの多くはJavaをやっていて、Seasarプロジェクトにも優秀な方々がたくさん参加していました。また、Seasarプロジェクトは他のコミュニティが主にユーザーのコミュニティであったのと比べると、自分たちでフレームワークを開発するというオープンソースの文化が色濃く出ていたんです。

だからこそ、Seasarプロジェクトに所属していた方々が醸成したオープンソースの文化が、後々に日本国内のさまざまなユーザーコミュニティにも伝わっていったように思います。もしもSeasarプロジェクトがなかったら、日本で「オープンソースにコミットする」という文化が生まれるのは何年か遅れていたと思います。日本人が多く開発にたずさわるRubyの流行を待たなければいけなかったかもしれませんね。

きしだなおきさん右向き

——日本におけるオープンソースコミュニティの源流が、その時期にできたのですね。SeasarといえばDI(Dependency Injection)とAOP(Aspect Oriented Programming)を実現するフレームワークですが、同様の概念を実現するものとしてSpring Framework(以下、Spring)も極めて有名ですよね。

きしだ Springの普及に関しては『Expert One-on-One J2EE Development without EJB』という書籍の影響が大きいです。この本はSpringの作者であるRod Johnsonの著作で、SpringとHibernateを用いてアプリケーションを開発しながら、Springの設計や機能について解説しています。この本が2004年に出版されたことをきっかけに、Springが一気に普及した印象があります。

書籍のタイトルである“without EJB”に現れていますが、「Springを用いることで、Enterprise JavaBeans(EJB)を使わなくてもアプリケーションが開発できる」というのが、当時は大きなウリでした。

EJBはIBMとSun Microsystemsによって提唱された仕様ですが、複雑な設定ファイルの記述が必要だったり、非常に大きなインターフェースを書かなければいけなかったりして使いづらかったんです。でも、Springが登場したことで「EJBを書かなくても、こういう設計でアプリケーションを作ることも可能なんだ」という驚きがありました。

OracleによるSun買収は、何を変えたか?

——きしださんの過去の登壇資料を拝見すると、2005年〜2010年のJavaが「停滞期」と記載されていました。なぜでしょうか?

きしだ この時期のJavaの停滞には、Sun Microsystemsの経営状況がもろに影響していると思います。当時のSun Microsystemsは経営難に陥っていました。

Sun Microsystemsは長期にわたりJavaをめぐる裁判をMicrosoftと行っていて、2004年にMicrosoftから19億ドルの和解金を受け取ったものの、経営状況は好転しない。その影響か、2006年に出たJava SE 6ではほとんど目立った新機能の追加がありませんでした。さらに2008年に発生したリーマンショックが、状況の悪化に追い打ちをかけました。その後、2010年にOracleによってSun Microsystemsが買収されたんです。

きしださんの視点による、Javaの歴史概観。ゼロ年代後半を「停滞期」と表現している。

——OracleによるSun買収以降、リリースや機能追加の流れは変わりましたか?

きしだ まず、買収の後にすぐJava SE7が出たことが大きいです。Java SE6がリリースされてからJava SE7が出るまで5年がかかっているんですが、この期間は先ほど話した経営難が影響しているのか、新機能の開発がほとんど進んでいなかったように感じます。開発とリリースのサイクルが、なかなかうまく回っていなかった5年だったという印象です。

ですが、Oracleによる買収以降、流れが変わりました。例えば、もともとはラムダ式やモジュールの機能がJava SE7に入る予定で、その実装後にJava SE7がリリースされる予定だったんです。しかしOracleは「実装できている機能をまずはきちんとリリースする」ということを優先して、ラムダ式やモジュールの導入をJava SE8まで見送る決断をし、Java SE7を早急にリリースしました。運営方針の違いが見えて面白いですよね。モジュールは結局Java SE 9まで持ち越されましたけど。

その後、リリースサイクルも半年のスパンに変化し、Javaのリリースがきちんと回る状態になってきました。

——いわゆる、停滞期だった頃のJavaと、リリースサイクルが早くなった現在のJavaとでは、どのような点に違いが出ていると思いますか?

きしだ 大きな機能の開発が着実に進むようになっていますが、面白いのは、細かい変更もちゃんと入るようになったことです。例えばJavaでは、要素数が3の配列に対して要素数の5番目を選ぶとArrayIndexOutOfBoundsExceptionが発生しますよね。

以前はこの例外が発生した場合には、java.lang.ArrayIndexOutOfBoundsException: 5のように表示されるだけで、あまり参考になるようなエラー出力ではなかったです。ですがJava 11からは「配列の要素は3つなのに5番目を選んだ」という趣旨の、より原因が把握しやすいエラー出力に変わったんです。

今までは、そういった細かい変更があまり入らなかったんですよ。例外メッセージの改善なんて、いったい何年放置されてたんだという。おそらく、その変更を入れてもリリースされるのは3年後とか5年後かもしれないという状態だと、中にいるエンジニアたちも小さい修正を入れるモチベーションが湧かなかったのでは、と。

でも、今のリリースサイクルならば、改修をして取り込まれたら半年後には必ずリリースされる。だからこそ、Javaのメンテナンスをしている方々のモチベーションそのものが向上している印象を受けます。

Javaならば「この書き方がベスト」と信じてコードを書ける

——これまで、メインで使う言語を他のものにする選択肢もあったかと思います。ですが、きしださんがJavaを使い続けてきたのってどうしてですか?

きしだ いえいえ、「他の言語をメインで使おうかな」と思うこともありますよ(笑)。

——そうなんですか。では、なぜJavaを使い続けてきたのでしょうか?

きしだ 他の言語を使うことで得られるメリットと、Javaによって実現できることを天秤にかけたときに「これ、Javaで書けばいいじゃん」と最終的に思ってしまうんですよね。結局、仕様を全て分かっている言語を使う方が、一番良い書き方ができるので。僕にとってはその言語がJavaです。

基本的に、僕が書いたコードはJavaとしては最適なコードになっているはずなんです。ある処理を実現するために何通りもの方法があるうち、「この書き方がベストだ」と信じて書ける。どうしてその書き方を選んだのかをきちんと説明できますし、迷ったときもどこを調べればいいのか分かる。

例えば、APIの裏側の処理はこうなっているから、こっちよりもこの書き方がいいとか、文字列の連結はこのバージョンからこうコンパイルされているからこれを使った方がいいとか、この機能は歴史的経緯で残っているだけで使わない方がいいとか。

きしだなおきさん左向き

——「信じて書ける」という言葉に、積み上げてきた知識の深さが伺えますね。例えば、初心者の方がやってしまいがちな「Javaの良くない書き方」の例はありますか?

きしだ 良くないというよりは、“より良い書き方”があるという感じですね。例えば、JDK9以降では基本的にArrays.asListよりもList.ofを使うほうがいい、などですかね。Arrays.asListが返すListは配列のラッパなのでサイズは固定でも要素の変更が可能なんですが、List.ofが返すListはきちんとimmutableになっていて要素の変更ができないようになっています。

それから、例えば複数のstreamで共通的に使うために、次のコード1のようにFunctionalInterfaceのフィールドを定義して、コード2のように使う方がいますよね。

// コード1
final Function<String, Price> CONVERT_STRING_TO_PRICE = 
  str -> str.substring(0, str.length() - 1).transfer(Price::of);
// コード2
return inputs.stream()
  .map(CONVERT_STRING_TO_PRICE)
  .collect(toList());

でもこれは、コード3のように普通にメソッドとして定義し、コード4のようにメソッド参照を使う方がいいです。

// コード3
Price stringToPrice(String str) {
  return str.substring(0, str.length() - 1).transfer(Price::of);
}
// コード4
return inputs.stream()
  .map(Converters::stringToPrice)
  .collect(toList());

なぜならば、ラムダ式を書くと内部では普通のメソッドが作られてメソッド参照が割り当てられているからです。つまり、メソッド定義を省略したつもりでも、結局はメソッドが作られているんですよ。

ならば、直接メソッドを作った方が処理と記術の差異がない。それに、FunctionalInterfaceは普通のメソッドよりも読むのが難しいですから、それよりは誰にとっても読みやすい書き方の方がいい。こういった「Javaをどう書くのがベストなのか」のパターンは以下にまとめています。

きっとまた、Javaが一番フィットする分野が現れる

——今後、Javaという技術は今後どのように使われていくと思いますか?

きしだ 前提として、Javaは次世代COBOLだと僕は思っているんです。COBOLが60年近く使われているように、Javaもこれから何十年も使われ続けるだろうと。多くの企業が過去にJavaで開発してきた業務システムを、他の言語にリプレイスする必然性は基本的にないですよね。そうするとJavaは今後も使い続けられるし、使い続けられるようにしていかないといけない。だからこそ、長期的な視野に立ってJavaを使い続けられるんです。

現在、Javaのリリースサイクルが変わって、新機能の追加も非常に活発になっています。そして、最新のハードウェア・ソフトウェアにフィットさせるような改善もずっと続けていますから、その努力を続けていれば、どこかでまたJavaがもっとも適した領域が現れて、大きな波が来るだろうと僕は思っています。

プログラミング言語の流行り廃りはありますが、90年代のCや2000年代のJavaのように、なにか1つの言語が世界を支配することは、今後あり得ないと考えています。

きしだなおきさん正面2

——最後に、きしださんの思う「Javaが持つ良さ」について教えてください。

きしだ Javaは全部ができる言語だということですね。デスクトップアプリも、サーバーサイドも、スマホアプリも、業務系のアプリもサービス系のアプリもできる。機械学習は、まだそんなに向いていないですけど、きっと将来的にはもっと楽にできるようになる。Javaを習得することで、さまざまな領域に手を出せるのが利点だと思ってます。

それから先ほども話に出たように、Javaは新しい要素技術にフィットしていこうとする努力を続けていますから、その流れに追従していくと自分自身が新しい技術を勉強するモチベーションになります。言語だけではなく、ライブラリやフレームワーク、実行系も全部まとめてJavaなんです。守備範囲の広さが、Javaの一番いいところですよね。

関連記事

取材・執筆:中薗昴