
とりあえず書くことが決まっていないので、走り書き状態のメモです。
言語仕様とjava.langパッケージについてかな? java.langだけかな?
java.lang の不自由な部分は独自にライブラリ作ってるので、そっち使うことも多いんですけどね・・・。
どの言語でも重要なのは、基本データをどのように扱えるかです。
int、char、double、などの基本型から、Stringクラス、配列などの扱いまでひととおりできるようになると、適度なソフトもつくれるのではないでせぅか。というわけで、今回は文字列などについて、いろいろとつんつんしてみませう。
文字列は、JavaではUnicodeを使用しています。String クラスやStringBufferクラス、char 型などを利用することができます。入出力にも、Reader/Writer系のクラスが用意されています。
どの程度のUnicodeかというと、ISO 10646でいうUCS-2(基本多言語面のみ)程度のようです。バージョン的にはUnicode 3.0なのかなぁ。
文字のこまかな処理をする場合、どのような容器を使うでしょうか。char 型の配列、StringBuffer、Stringの3種類あると思うのですが、何も意識していないとついついStringを使ってしまい、無駄なオブジェクトを乱立させて速度低下を起こしてしまいがちです。
ひらがなカタカナ変換、全角半角変換のような機能は、英字のようにStringクラスに標準装備されることはなさそうです。net.siisise.lang.String というクラスで実現してみました。このような機能は、自作することをおすすめします。
JavaだからUNICODEだから文字コードは意識しなくていいというわけでもなくて、ひらがな文字のコードはどこからどこまでだとか、知っておかないといろいろ作れないですね。
問題点
Unicode 3.1で定義されはじめたUnicodeの補足エリア(U+10000以降)や、それ以前から存在する合字については、現在のStringクラスでは対応できないのではないだろうか。対応できるとしても、ソフトウェアの見直しが必要。たとえばlength()が文字数を返すのかcharの数を返すのか。charAt(int)についても、合字やサロゲートを使った文字を返せない。charの何番目かと割り切って使うべきか。
Java 2 Platform 1.5以降で対応される予定。
問題その2
Shift_JISとWindows-31J、この2つの文字コードがUnicode上で異なる。基本的にShift_JIS側を使うのか、Windows-31J側を使うのか決めて、全体のコードを統一しなければならない。Windows上で動作する場合には、Windows-31Jが使われていることが多いので、Shift_JISを全く使わないという方向に進んでいくのかもしれない。しかし、そうするとEUC-JPとの変換で問題が生じることになる。EUC-JPは、Shift_JISと同じUnicode上のコードを使っている。Windows-31Jを使う場合には、EUC-JPとの混在は不可能である。UTF-8などを外部出力の場合にも使用していくことで、この問題はいくらか解決していくのかもしれない。
違いは、Stringクラスがインスタンスの中を変更できないのに対して、StringBufferは変更可能ということです。変数はどちらでも変更できますが、・・・。
java.lang.Thread クラスと、java.lang.Runnable ですか。
これは・・・パラメータ渡しができない、という点で不便です。
POSIXのスレッドってパラメータ渡しとかできたような気がするのですが、できなかったっけ・・・。
そういうわけで、net.siisise.ParamThreadなんていうクラスを作る事にしました。
スレッド分けしてはいけないもの、というのがあるのですね・・・。なんでもかんでもスレッドにしてしまおうとすると、なんか失敗してしまいそうになってしまいましたよ。
見ててよくないなと思ったのは、アニメーションの場面ですねぃ。キャラクタ1つ1つにスレッドを割り当てると独立した行動ができそうですが、ここはアニメーション系のスレッドは1つだけにして、各キャラクタに順番に処理を割り振るようにしたほうがいいです。特にゲームなんかの場合そうです。
キー入力なんかもたぶん割り込み等々で処理されてるんだと思うのですが、これもメインのスレッドとまとめてほしぃなと思うところです。キーを押すたびにイベントキューには溜まるのですが、別スレッドにしてしまうと取り出しまでにアニメーションがずいぶんと時間差攻撃を受けてしまいました。悲し。
困っているのは、描画系かもしれません。repaint() なんてメソッドを呼び出したあとは、メインのルーチンでは次の描画のための計算をはじめてしまいますね。しかし、描画のための機能は、もう少しあとにならないと呼び出されないので、ちらちらとしてしまうことが多々あります。
まぁ・・・描画のためのデータをどこかにまとめて蓄えておくしかないのでしょうね。ダブルバッファとか、そういうので。定石ではありますが、悲し。