愚痴です。
最近仕事で Android の開発をしているのですが、Java の扱いづらさに悪戦苦闘しております。
もともと Java の利点は、プラットフォームに関係なく JavaVM 上で共通のプログラムが動く、というものだったと思います。最初は 100% Pure Java なんて言い方をしてましたね、確か。それが現在は、jni などという仕組みを導入してネイティブコードの呼び出しを許してしまうことで、この利点は失われてしまいました。さらに、携帯や Android は独自のライブラリを持っており、各機種で共通に動作するようなプログラムを作ることもできません。
さらには Java という言語の仕様も C++ プログラマから見るとあまりにも不完全で、ガベッジコレクションのような機能も、もはや不便なものでしかありません (後述)。
Java ってもう、いろいろ駄目なんじゃね?という愚痴です。
●ガベッジコレクションという足枷
ガベッジコレクションは、不要になった (どこからも参照されていない) メモリを自動的に解放してくれるものですが、これが C++ に慣れたプログラマにとっては非常に不便な機能です。なぜならこれは、いつ解放されるかプログラマが知ることはできないからです。
C++ プログラマは普通、初期化処理をコンストラクタに書き、終了処理をデストラクタに書きます。そして、そのクラスをスコープの中で使用すると、処理がスコープの外に出る際に必ずデストラクタが呼ばれることがわかっています。ですから、メモリの解放以外の終了処理、例えばリソースの解放処理やファイルのクローズをデストラクタに書き、これらの終了処理のし忘れを確実に回避することができます。
しかし Java や .NET のようなガベッジコレクションのシステムではメモリがいつ解放されるかわからない=デストラクタの呼ばれるタイミングがわからないため、このような終了処理をデストラクタに書くことができません。つまり、ファイルのクローズなどをプログラマが毎回手動で行うしかないわけです。これにより、終了処理のし忘れというバグをいつまでも作り続ける恐れがあります。
メモリの自動開放についても、C++ ではスマートポインタの導入により、昔のようなメモリリーク問題はほぼなくなってきています。しかも、スマートポインタならメモリ解放のタイミングもプログラマが予測可能なので、メモリ残量のコントロールも可能です。
ガベッジコレクションはこのように、予測不能であるために、プログラマにとっては足枷でしかないのです。
●処理が異常に重い
どこかの段階から Java では JIT という機能が追加され、内部で Java マシンコードを各プラットフォームにネイティブなコードに置き換え高速化するという機能が実装されたそうです。しかし、JIT で最適化する際の効率化のため、Java コンパイラ自体はほとんど最適化を行わないのだとか。そのおかげで JIT を搭載していない携帯機等では、とてつもなく動作速度が遅くなります (Android は 2.2 以降で実装されているそうですが)。これをなんとかするために、携帯機のプログラマは涙ぐましいまでの苦労を強いられます。
特にひどいのが、オブジェクト指向なプログラムをすると呼び出しコストが高くなるので、クラスの数をなるべく少なくする必要があるというものです。僕が見たものの中には、クラスが1つしかなく、その中に大量のメンバ変数と、メソッドが並んでいるというようなものもありました。昔懐かしい構造化プログラミングとかが必要になるレベルです。
JIT を搭載していないシステムでは、まともなものは作れなくなっているように思います。
●プリプロセッサがない
移植性を高くするため、機種依存のコードは、コンパイル時に選択するようにしたいものです。C 言語では昔からプリプロセッサを利用して、このようなコードの切り分けを行ってきました。
しかし、Java にはこのようなものがありません。多くの Java プログラマは C 言語用のプリプロセッサを利用しているようです。
このような状況であるにもかかわらず Java がプリプロセッサを正式に採用しないのはなぜなんでしょう?一部には Java のコンセプトに合わないとかなんとか。しかし、これがないと、機種毎に違うコードを用意するためにソースを別々に書き、別々にメンテナンスする必要が発生します。これはプログラマにとって大きな負荷となり、更新し忘れなどが頻繁に発生することになるでしょう。
バグを増やす可能性を増やしてまでこだわるコンセプトってなんですか?と問いたい。
●開発環境
Java での統合開発環境は eclipse が一般的のようです。eclipse は Java で書かれているそうで、このため処理が異常に重いです。また、メモリも大量に必要とし、メモリが不足すると落ちます。あまりに不便なため、コマンドラインだけで開発している人も多いのではないでしょうか?しかし、デバッガは GUI が欲しいところ…。
こだわりなのかなんなのか知りませんが、なんでもかんでも Java である必要はないのではないでしょうか。
…とかいろいろ書きましたが現状どうしようもなく、仕事はこれでやらなきゃならないわけで。
まあ、Anidroid 自体の開発はおもしろそうなので、個人的に自分専用の Andoird 開発用 IDE でも作ってみるかな。もちろん C++ で!