So-net無料ブログ作成

『プログラミング言語Java第4版』正誤表を更新しました [正誤表]

書籍『プログラミング言語Java第4版』の正誤表を更新しました。

http://www001.upp.so-net.ne.jp/yshibata

可変長パラメータと配列パラメータの互換性 [Java]

メソッドがオーバーライドされる場合、スーパークラスでは引数型が配列と宣言されたメソッドを、サブクラスで可変長パラメータと宣言したり、スーパークラスで引数型を可変長パラメータと宣言されたメソッドを、サブクラスで配列と宣言したりすると、JDK 5.0リリースではコンパイルができますが、警告メッセージが出力されていました。

たとえば、次のAクラスとBクラスを見てみてください。
class A {
    void f(Object... o) { }
    void g(Object[] o) { }
}

class B extends A {
    void f(Object[] o) { }
    void g(Object... o) { }
}

JDK 5.0では、これらのクラスをコンパイルすると警告メッセージが出ていました。しかし、Java 6では、警告メッセージは何も出ることなくコンパイルされるようになっているようです。JDK5.0がリリースされた時点では、将来はコンパイルエラーされる可能性も考えられていましたが、Java 6では警告は何も出ないようになっているので、将来コンパイルエラーとされる可能性はほとんどないでしょう。

しかし、警告が出なくても、やはり、どちらのオーバーライドも好ましくないでしょう。
class Test {
  public static void main(String[] args) {
    B b = new B();
    A a = b;

    a.f(1, 2, 3);
    b.f(1, 2, 3);

    b.g(1, 2, 3);
    a.g(1, 2, 3);
  }
}

このTestクラスをコンパイルすると次のようにエラーとなります。
Test.java:10: g(java.lang.Object[]) (A 内) を (int,int,int) に適用できません
    a.g(1, 2, 3);
     ^
エラー 1 個

Bクラスのfメソッドは、可変長パラメータと同じように呼び出せています。gメソッドの場合には、参照の型によって、スーパークラスは配列パラメータ、サブクラスは可変長パラメータと見なされていることになります。

[追記: 2009年5月2日]
一部訂正ブログを書いていますので、そちらも参照してください。

書籍『上流行工程で成功する人、つまずく人』 [プログラマー現役続行]

上流工程で成功する人、つまずく人 (技評SE新書)

上流工程で成功する人、つまずく人 (技評SE新書)

  • 作者: 荒井 玲子
  • 出版社/メーカー: 技術評論社
  • 発売日: 2009/01/24
  • メディア: 単行本(ソフトカバー)

荒井玲子さんの新著『上流行工程で成功する人、つまずく人』が著者である荒井さんから私の自宅に送られてきました。

「あとがきに」に次のように述べられています。
 いつからソフトウェア技術者という職業は、これほど嫌われる職業になってしまったのでしょうか。いまや3K職種のひとつと言われるまでになってしまいました。
 "IT"や"コンピュータ"というと、何か特別の響きをもって話題にのぼるのにもかかわらず、ソフトウェア技術者というと、とたんに人気がなくなってしまうのを、大変悲しく思います。私は、ソフトウェア技術者ひとりひとりに、自分が選んだソフトウェア開発という仕事に誇りに思ってほしいからです。
 (途中省略)
 本書を読んでいただいた、ソフトウェア技術者の方には、「自分の仕事は知識労働であり、知識労働らしい成果物をつくっていく」と考えてほしいと思います。また、ひとりでも多く、この仕事に誇りを持っていただけたら、と願っています。
 (以下省略)

私自身、彼女のこの言葉には同感です。若いソフトウェア技術者には、第二部「プロジェクト編」を是非読んでもらいたいと思います。

The Boy Scout Rule [プログラマー現役続行]

Clean Code: A Handbook of Agile Software Craftsmanship (Robert C. Martin Series)

Clean Code: A Handbook of Agile Software Craftsmanship (Robert C. Martin Series)

  • 作者: Robert C. Martin
  • 出版社/メーカー: Prentice Hall
  • 発売日: 2008/08/11
  • メディア: ペーパーバック

読みやすいコードを書くことの重要性については、拙著(『プログラマー現役続行』)の中でも述べていますが、書籍『Clean Code』には、次の記述があります。

It’s not enough to write the code well. The code has to be kept clean over time. We’ve all seen code rot and degrade as time passes. So we must take an active role in preventing this degradation.

The Boy Scouts of America has a simple rule that we can apply to our profession.

Leave the campground cleaner than you found it.

If we all checked-in our code a little cleaner than when we checked it out, the code simply could not rot. The cleanup doesn’t have to be something big. Change on variable name for the better, break up one function that’s a little to large, eliminate one small bit of duplication, clean up on composite if statement.

Can you imagine working on a project where the code simply got better as time passed? Do you believe that any other option is professional? Indeed, isn’t continuous improvement an intrinsic part of professionalism?

ここで述べられているように、些細な改善であっても、常に改善する心がけにより、コードは腐ることなく、時間の経過に伴って良くなっていくことになります。

今日では、テスト駆動開発により、開発しているソフトウェアの機能を確認するためのテストコードが書かれているプロジェクトも多いと思います。そのような開発では、コードの改善による機能のデグレードがないかをテストコードの実行により容易に確認可能であり、このボーイスカウト・ルールが容易に実践できることになります。

また、テストファーストによる開発では、最初にテストコードを作成して、そのテストに合格するように実装してくわけです。そして、すべてのテストに合格したら、実装が終了と思っているエンジニアは多いのではないでしょうか。しかし、そこで実装が終了と思っているようでは、駄目です。

コードがクリーンに書かれているかを見直し、そうでなければクリーンにするためのリファクタリングを行う必要があります。そして、自分で見てもある程度納得できるクリーンなコードになったら、最初の実装が終了となります。誰でも最初からクリーンなコードを書けたりはしません。したがって、テストコードによる動作確認が済んでも実装は終わりではなく、コードをクリーンにする作業を行って実装が終了と考えることは、ソフトウェアエンジニアにとっては重要なことです

iPod nanoを購入 [英語]

Apple iPod nano 16GB ブラック

Apple iPod nano ブラック

  • 出版社/メーカー: アップル
  • メディア: エレクトロニクス

今までは、ケーブルテレビからCNNを録音して聞くためにMDに録音して、ソニーのMD Walkmanを使用していました。MDに録音するのが面倒になってきたので、iPod nanoを購入しました。早速、CNNのサイトから最新のPodcastのニュースなどをMacBook上のiTunesに登録して、ダウンロードし、iPodへ転送しました。2インチカラー液晶ディスプレイで再生するPodcastは鮮明であり、36.8gの重量は非常に軽いです。

英語勉強法(2)で述べたように、大学時代にソニーのカセットテープのWalkmanを使用していた頃から比べると、今日ではネイティブの英語を非常に手軽に入手して聞ける時代になりました。語学の修得には、学んでいる言語にどれだけ接している時間の総量が重要だと思います。接し方は、聞いたり、読んだり、話したり、書いたりとありますが、仕事で英語を使用する機会がない場合には、やはり通勤中に生の英語を聞いて、英語に触れる必要があると思います。

ただ、聞くだけでは英語力は伸びません。英語勉強法(2)で述べたように、「読んで分からないものは、聞いても分からない」ので、読むことも重要です。それも、頭から理解しながら読む努力を地道に継続する必要があります。

[講演] 建設システム様 [プログラマー現役続行]

(株)ラグザイア(http://www.luxiar.com/)の相馬副社長のご紹介で、1月17日(土)に新富士にある建設システム様(http://www.kentem.jp/)で、2時間の講演をさせて頂きました。新幹線で新横浜駅から新富士駅まで行ったのですが、新幹線を降りると、改札を出る前の柱に建設システム様の大きな宣伝が貼ってあり、駅を出るとそこには富士山が奇麗に大きく見えていました。

P1010747.jpg
(帰りに新富士駅から撮った富士山です)

建設システム様を訪問すると、社員の皆様が挨拶をしてくださり、礼儀正しい社員の方々でした。2時から会議室で講演を初めて、途中1回休憩して、4時頃に終了しました。内容としては、拙著『プログラマー現役続行』 の内容に沿って以下のテーマで話をしました。
  • 一人前になるには10年
  • 読みやすいコードを書く
  • 論理的思考
  • 継続した学習
  • 英語力
  • コミュニケーション力
  • 朝型の勧め
  • ソフトウェア・スキル・インデックス
  • 「型」覚えずして上達なし
  • 書籍紹介
  • Google Web Toolkitデモ

拙著の内容を読まれていると、話の8割はすでに述べていることなのですが、できるだけ私自身が最近新たに考えていることなどを織り込むようにはしています(が、新し話を盛り込むことはなかなか難しいです)。

若い社員の方々が多く出席されて聴いてくださりましたが、私の話は多少現実離れしているように聞こえた部分もあったかも知れません。しかし、何か一つでも参考になって、これからのソフトウェア開発で心がけてくださればと思っています。

アノテーションの互換性 [Java]

『プログラミング言語Java第4版』の第16章「リフレクション」の16.2節「アノテーションの問い合わせ」では、リフレクションを使用してのアノテーションの問い合わせ方法が解説されています。その節の最後の段落に次のような記述があります(363頁)。
実行時に存在するアノテーション型は、調べられようとしているクラスにアノテーションを付けるのに使用されたアノテーション型と異なる可能性がありますので、その型の2つの使われ方には互換性がない可能性があります。もし、互換性がない場合に、アノテーションの要素へアクセスしようとすると、AnnotationTypeMismatchExceptionあるいは IncompleteAnnotationExceptionがスローされます。もし、要素型がenumであり、アノテーション内のenum定数がそのenumに存在しなくなっていれば、EnumConstantNotPresentExceptionがスローされます。

この説明によれば、アノテーションは、互換性がある方法で変更することが可能だということになります。互換性を保ちながらアノテーションを変更できるという意味で、『Effective Java 第2版』には、次のように述べられています(174頁の最後の段落)。
マーカーインタフェースに優るマーカーアノテーションの主な長所は、デフォルトを持つアノテーション型要素を1つ以上追加することで、すでに使用された後でもアノテーション型に情報を追加できることです [JLS, 9.6]。単なるマーカーアノテーション型として始まっても、時間の経過に伴い機能が豊富なアノテーション型へ発展できます。そのような発展は、マーカーインタフェースでは不可能です。なぜなら、一旦実装された後に、インタフェースにメソッドを追加することは一般に不可能だからです。

つまり、既存のアノテーション型の定義に新たな要素を追加する場合には、デフォルトを指定すれば互換性を保ちながら変更が可能だということです。

実際に、既存のアノテーション型にデフォルトを持たない要素を追加した場合には、そのアノテーション型でアノテーションを付けられているコードを再コンパイルするとエラーになります。なぜならば、新たな要素の値が指定されていないからです。しかし、再コンパイルされない場合に、リフレクションによりその新たな要素の値を読み出そうとすると、IncompleteAnnotationExceptionがスローされます。

既存のアノテーション型の特定の要素の型を変更した場合には、そのアノテーション型でアノテーションを付けられているコードを再コンパイルするとエラーになったり、ならなかったりします。たとえば、元の要素の型がStringであったのををintにすればコンパイルエラーとなります。一方、元の要素の型がStringであったのを配列String[]に変更した場合には再コンパイルできます。なぜならば、要素の値が少なくとも1つはすでに指定してあるからです。しかし、どちらの場合でも、古いアノテーション型でアノテーションが付けられているコードを再コンパイルすることなく、そのアノテーションの要素の値をリフレクションにより読み出そうとするとAnnotationTypeMismatchExceptionがスローされます。

Java言語のアノテーションについてはきちんと学びたい方は、『プログラミング言語Java第4版』の第15章「アノテーション」と16.2節「アノテーションの問い合わせ」、および、拙著『Java 2 Standard Edition 5.0 Tiger―拡張された言語仕様について』の第7章「アノテーション」と8.1節「リフレクションAPI」を読まれることをお勧めします。


Top Java Developers Offer Advice to Students [Java]

Sun Developer Networkに「Top Java Developers Offer Advice to Students」と題する記事が掲載されています。これは、過去のインタビュー記事のダイジェスト版になっており、各インタビューの最後には元のインタビュー全文へのリンクがあります。

Top Java Developers Offer Advice to Students

『Effective Java 第2版』正誤表を更新しました [正誤表]

先日正誤表をアップしたと書きました。

http://yshibata.blog.so-net.ne.jp/2008-12-26

今日、次の項目を追加しました。
  • 262頁: 1行目の[Bloch01, 項目50]は、[Bloch01, 項目49]の誤り。(原著の変更内容)