Java 2 SDK 開発ガイド (Solaris 編)

以前のリリースとの互換性

このマニュアルでは、次のトピックについて説明します。

Java 2 Platform のバージョン 1.3 と 1.2 の非互換性については、http://java.sun.com/j2se/1.3/ja/compatibility.html にある Java 2 Platform バージョン 1.3 の互換性に関するドキュメントを参照してください。

Java 2 Platform のバージョン 1.2 と 1.1 の非互換性については、http://java.sun.com/j2se/products/jdk/1.2/ja/compatibility.html にある Java 2 Platform バージョン 1.2 の互換性に関するドキュメントを参照してください。

Java 2 Platform のバージョン 1.1 と 1.0 の非互換性については、http://java.sun.com/products/jdk/1.1/compatibility.html にある JDKTM 1.1 ソフトウェアの互換性に関するドキュメントを参照してください。

バイナリ互換性

JavaTM 2 SDK, Standard Edition, (J2SETM) バージョン 1.4 は、次に示す非互換性を除いて、J2SE 1.3 との上位バイナリ互換性を持っています。つまり、この非互換性を除けば、バージョン 1.3 コンパイラで構築したクラスファイルは J2SE 1.4 でも正しく動作します。

一般的に、ポリシーは次のとおりです。

初期のバイトコードオブファスケータの中には、仮想マシンの仕様とは異なる形式のクラスファイルを生成するものがありました。このような不適切な形式のクラスファイルは J2SE の仮想マシン上では動作しませんが、初期バージョンの仮想マシン上では動作するものもあります。この問題を修復するには、適切な形式のクラスファイルを生成する新しいオブファスケータでクラスファイルを生成し直します。

ソース互換性

J2SE 1.4 は、次に示す非互換性を除いて、初期バージョンとのソースの上位互換性を持っています。この非互換性を除けば、初期リリースで定義された言語機能や API を使用するように書かれたソースファイルは J2SE 1.4 でもコンパイルおよび実行できます。

ソースの下位互換性はサポートされません。新しい言語機能や Java 2 Platform API を使用するソースファイルは、初期バージョンの Java 2 Platform では使用できません。

一般的に、ポリシーは次のとおりです。

非推奨 API は下位互換性だけをサポートするメソッドやクラスであり、このような API を使用していると、-nowarn コマンド行オプションを指定していない限り、コンパイラは警告メッセージを生成します。非推奨メソッドやクラスを使用しないようにプログラムを変更することが推奨されますが、現在のところ、このようなメソッドやクラスをシステムから完全に削除する計画はありません。

sun.* パッケージ内のいくつかの API は変更されました。これらの API は開発者向けではありません。 sun.* パッケージからインポートする場合、開発者は自分の責任で行うようにしてください。詳細については、http://java.sun.com/products/jdk/faq/faq-sun-packages.html にある『Why Developers Should Not Write Programs That Call sun.* Packages』を参照してください。

Java 2 Platform, Standard Edition, バージョン 1.4 における非互換性

J2SE 1.4 は以前のバージョンの Java 2 Platform との強力な互換性を持っています。既存のプログラムは変更しなくても、ほとんどすべて、J2SE 1.4 上で動作するはずです。しかし、まれな状況や「コーナーケース」で発生するいくつかのマイナーな潜在的な非互換性も存在しているためその状況に対処できるように補足としてここで説明します。

  1. Java 2 Platform バージョン 1.4 以降、クラス javax.swing.tree.DefaultTreeModel は null のルートノードの設定が可能です。以前のバージョンでは、TreeModel の仕様で null のルートが有効であると示されているのにもかかわらず、DefaultTreeModel は null のルートを許可しませんでした。DefaultTreeModel は現在、null のルート設定が可能であり、コンストラクタ内の null のルート設定も可能です。この変更の一部として、DefaultTreeModel.setRoot() の仕様も改訂されました。DefaultTreeModel.setRoot() の古い仕様は次のとおりです。

    ルートをルートに設定します。これによって、ルートが null の場合、IllegalArgumentException がスローされます。

    DefaultTreeModel.setRoot() の新しい仕様は次のとおりです。

    ルートをルートに設定します。ルートが null の場合、ツリーには何も表示されませんが、正当であることを意味します。

  2. 直列化可能な内部クラスにそのクラスオブジェクトへの明示的な参照が含まれる場合、そのクラスのシリアルバージョン UID の値は J2SE 1.3 と J2SE 1.4 で異なります。この違いは、J2SE 1.3 と J2SE 1.4 との間で javac コンパイラで行われた変更がシリアルバージョン UID の計算に影響を与えているためです。

    この問題を回避するには、明示的なシリアルバージョン UID を直列化可能なクラスに追加することが推奨されます。serialver ツールを使用すると、J2SE 1.3 の javac コンパイラでコンパイルされたクラスのシリアルバージョン UID を取得できます。

  3. J2SE 1.4.0 以降、クラス javax.swing.text.DefaultHighlighter の public static フィールド DefaultPainterfinal です。 以前のバージョンの Java 2 Platform, Standard Edition では、このフィールドは final ではありませんでした。

  4. J2SE 1.4.0 では、HTML フォームが Java 2 Platform の実装に内部的にモデル化される方法が変更されました。 以前のバージョンでは、フォームの属性はすべての子の文字要素の属性セットに格納されていました。J2SE 1.4.0 では、HTML ファイル自身のフォームによりフィットするフォームを表す要素が作成されます。これによって、フォームがより良くモデル化されるようになり、フォームを一貫して書き出せるようになります。この変更は、バグ 4200439 に対処するために行われました。

    この変更は、正確に処理されていないフォームを使用している開発者に影響します。たとえば、次のような無効な HTML を想定します。


    <table>
    <form>
    </table>
    </form>

    1.4.0 より前の実装では、次のように扱われます。


    <form>
    <table>
    </table>
    </form>

    J2SE 1.4.0 では、次のように扱われます。


    <table>
    <form>
    </form>
    </table>

    この変更は多くの開発者にはあまり影響しないように見えますが、自分のコードを更新する必要がある可能性はあります。以前、リーフの要素の属性がフォームの属性に含まれていると想定していた場合、1.4.0 以降、このような属性はフォームの要素の属性セットから取得する必要があります。

  5. J2SE 1.4.0 以降、クラス java.awt.event.MouseEventstatic final フィールド MOUSE_LAST の値は 507 に変更されました。以前のバージョンの Java 2 Platform では、MOUSE_LAST の値は 506 でした。

    コンパイラは static final の値をコンパイル時にハードコード化するので、MOUSE_LAST を参照する、1.4.0 より前のバージョンの java.awt.event.MouseEvent でコンパイルされたコードは古い値のままです。このコードを J2SE 1.4.0 で動作させるには、バージョン 1.4.0 のコンパイラでコンパイルし直す必要があります。

  6. J2SE 1.4.0 で出荷される CORBA テクノロジ用の API は OMG ドキュメントで指定されている CORBA 2.3 マッピングに準拠するように変更されています (OMG ドキュメントについては、http://java.sun.com/j2se/1.4/ja/compatibility-CORBA.html にある『CORBA Compatibility Information』オンラインドキュメントを参照)。J2SE v1.3 と v1.4.0 の間で行われた CORBA 機能に関連する API の変更については、上記ドキュメントと同様に、J2SE 1.4.0 が準拠しているすべての OMG 仕様の一覧を参照してください。

  7. J2SE 1.4.0 以降、 ObjectOutputStream.putFields または ObjectOutputStream.writeUnshared を無効にするサブクラスによって (直接的または間接的に) 呼び出される場合、ObjectOutputStream の引数を 1 つ取る public コンストラクタは「enableSubclassImplementation」である SerializablePermission を必要とします。

    また、J2SE 1.4.0 以降、ObjectInputStream.readFields または ObjectInputStream.readUnshared を無効にするサブクラスによって (直接的または間接的に) 呼び出される場合、ObjectInputStream の引数を 1 つ取る public コンストラクタは SerializablePermission の「enableSubclassImplementation」を必要とします。

    この変更はほとんどのアプリケーションにはあまり影響ありません。しかし、putFields または readFields メソッドをオーバーライドするが、直列化インフラストラクチャの残りの部分はオーバーライドしない ObjectInputStream/ObjectOutputStream サブクラスは影響を受けます。

  8. J2SE 1.4.0 の Javac バイトコードコンパイラは以前のバージョンよりも厳密に Java 言語仕様に準拠しています。Java 言語仕様に厳密に準拠しない既存のコードは、初期バージョンのコンパイラでコンパイルできていた場合でも、新しいコンパイラではコンパイルできないことがあります。

    次に、J2SE 1.4.0 コンパイラがより厳密である例を示します。

    • 新しいコンパイラは到達不能の空文を検出します (Java 言語仕様で定義されているとおりに)。次に、現在のコンパイラが検出および拒否する一般的な例を 2 つ示します。


      return 0;/* exit success */;

      および


      {
          return f();
      } catch (Whatever e) {
          throw new Whatever2();
      };

      2 つの例には両方ともに余分なセミコロンが付いていて、新しいコンパイラはこのセミコロンを到達不能の空文であると見なします。さらに、自動生成されるソースコードは到達不能の空文を生成することがあります。

    • 新しいコンパイラは、名前のない名前空間からタイプをインポートする import 文を拒否します。以前のバージョンのコンパイラは、言語仕様では許可されていないにもかかわらず (import 節に現れるタイプ名はスコープ内ではないため)、このような import 宣言を受け入れていました。仕様には、単純名は import 文では使用できず、また、名前のない名前空間からはインポートできないと明確に宣言されています。

      要約すると、


      import SimpleName;

      この構文は現在有効ではありません。また、


      import ClassInUnnamedNamespace.Nested;

      この構文も現在有効ではなく、名前のない名前空間からは入れ子になったクラスをインポートしません。このような問題を修正するには、すべてのクラスを名前のない名前空間から名前付きの名前空間に移動します。

  9. J2SE 1.4.0 では、javac バイトコードコンパイラはデフォルトの動作として、以前の「-target 1.1」ではなく、「-target 1.2」を使用します。これらのオプションの動作については、http://java.sun.com/j2se/1.4/ja/docs/ja/tooldocs/solaris/javac.html にある javac コンパイラのリファレンスページを参照してください。「-target 1.2」に関連する変更の 1 つとして、クラスが実装されていないメソッドをインタフェースから継承する場合、コンパイラは現在、メソッド宣言をクラスファイルに生成および挿入しません。このように挿入されるメソッドは、他のすべての非公開メソッドのように、デフォルトの serialVersionUID 計算に含まれています。結果として、インタフェースを直接実装するが、そのメソッドのうち 1 つでも実装しない抽象的な直列化可能クラスを定義した場合、そのデフォルトの serialVersionUID 値は、J2SE 1.4 の javac または以前の javac のどちらでコンパイルしたかによって異なります。

    このような初期バージョンの javac によって挿入されるメソッドに関する情報については、http://java.sun.com/jdc/bugParade/bugs/4043008.html にあるバグ 4043008 の報告を参照してください。

  10. ソース互換性 - JDBC 3.0 API (J2SE 1.4 の一部として含まれる) は 2 つの新しいインタフェースを導入し、いくつかの新しいメソッドを既存のインタフェースに追加しました。初期バージョンの JDBC API を使用するドライバおよびアプリケーションは J2SE 1.4 とバイナリ互換性を持っており、何の問題もなく動作します。しかし、JDBC 3.0 API で行われた変更にはソース互換性がありません。JDBC インタフェースを実装するドライバおよびアプリケーションを正しく構築するには、この変更を反映させるように更新する必要があります。『JDBC 3.0 Specification』の第 6 章には、JDBC 3.0 API に準拠する (つまり、J2SE 1.4 とソース互換性を持つ) ために行う必要があるすべての事項が一覧表示されています。

  11. J2SE 1.4 より前では、ファイルタイプが判明しており、応答コードが 400 以上になった場合、FileNotFoundException がスローされます。そうでない場合、例外はスローされません。J2SE 1.4 で実装された正しい動作は、URLConnection.getInputStream に関しては、ファイルタイプにかかわらず、すべての HTTP エラーに対して IOException をスローし、HTTP 応答がリソースが見つからないことを示している場合だけ、IOException のサブクラスである FileNotFoundException をスローします。言い換えると、FileNotFoundException がスローされるのは、応答コードが 404 または 410 の場合だけです。この変更の一部として、現在、HttpURLConnection.getErrorStream を使用すると、サーバから戻されたエラーページを読み取ることができます。J2SE 1.4 より前では、getErrorStream は常に null を戻していました。また、メソッド HttpURLConnection.getResponseCode は J2SE 1.4 で正しく動作します。

  12. J2SE 1.4 では、assert キーワードが Java プログラミング言語に追加されました。新しいキーワードのため、「assert」を識別子として使用している既存のプログラムは J2SE 1.4 に準拠しません。しかし、このキーワードが追加されたからと言って、既存のバイナリ (.class ファイル) を使用しても問題は発生しません。(「assert」が正式な識別子であった) J2SE 1.4 より前のリリースから (「assert」が正式な識別子でない) J2SE 1.4 への移行を簡単にするため、J2SE 1.4 の Javac バイトコードコンパイラは 2 つの動作モードをサポートしています。

    通常動作モードでは、コンパイラは以前のリリース (J2SE 1.3) の仕様に準拠するプログラムを受け入れます。アサーションが許可されていないので、assert キーワードが識別子として使用されている場合、コンパイラは警告を生成します。

    代替動作モードでは、コンパイラは J2SE 1.4 の仕様に準拠するプログラムを受け入れます。アサーションが許可されているので、assert キーワードが識別子として使用されている場合、コンパイラはエラーメッセージを生成します。

    アサーションを有効にするには、-source 1.4 コマンド行スイッチを使用します。このフラグがない場合、ソース互換性を最大限にするために、デフォルトの動作は「1.3」になります。1.3 とのソース互換性はいずれサポートされなくなる予定です。

  13. インタフェース java.applet.AppletContext の API 仕様は変更されて、アプレット開発者はブラウザセッション中にデータやオブジェクトをストリームしながら持続的に使用できるようになりました。これによって、開発者は静的なクラスを使用してデータやオブジェクトをキャッシュする必要がなくなりましたが、潜在的なバイナリ非互換性が生じています。AppletContext インタフェースを実装するクラスを含む既存のアプリケーションはすべて、新しい AppletContext 仕様と互換性がありません。このようなクラスは、改訂された AppletContext API を実装するように変更する必要があります。実際には、通常、AppletContext を実装しているアプリケーションは、JavaTM Plug-in やアプレットビューアなど、アプレットコンテナとして動作するアプリケーションだけです。したがって、この潜在的な非互換性の影響は最小限になると予想されます。

  14. J2SE 1.4 が Socket API に行なった重大な変更の 1 つとして、SocketImpl 抽象クラスに新しい抽象メソッドが追加されました。新しいメソッドのため、J2SE 1.4 よりも前に SocketImpl のサブクラスを作成していた場合、新しいメソッドに提供される実装が存在しないので、1.4 の javac ではコンパイルが失敗します。 バイナリ互換性は保たれているので、このサブクラスの既存のクラスファイルは予想どおりに動作します。

    SocketImpl のサブクラスを作成しているアプリケーションは少数であり、したがって、この潜在的な非互換性の影響は最小限になると予想されます。SocketImpl のサブクラスを作成している開発者がこの変更に対処するには、次の 2 つの方法があります。

    • J2SE 1.3.x (以前) でコンパイルしたクラスファイルを使用する

    • 新しいメソッドに実装を提供する