Sun Microsystems, Inc

いつ、どのように API を非推奨とするか

非推奨 API に関する
ホームページ

「非推奨」の意味すること

「自虐的 (self-deprecating) ユーモア」という言葉を聞いたことがあるかもしれません。つまり、自分自身を低めるユーモアのことです。非推奨 (deprecated) のクラスまたはメソッドは、それに似ています。もはや重要ではなくなったのです。つまり、そのクラスやメソッドの重要性は著しく低下しており、現在では他 のクラスやメソッドに置き換えられていたり、将来は存在しなくなる可能性もあるため、今後は使用するべきでないことを意味しています。

Java では、非推奨を表現する手段を提供しています。それは、クラスの発展に伴い、その API (アプリケーションプログラミングインタフェース) も必然的に変化するからです。一貫性を保つためにメソッドの名前が変更されたり、新しいメソッドや改良版のメソッドが追加されたり、フィールドが変更に なったりします。しかし、このような変更により別の問題も生じます。開発者が新しい API に移行するまで、古い API を維持する必要がある一方で、今後は古い API を使ってプログラミングを行わないよう伝えなければなりません。

クラスやメソッドやメンバフィールドを「非推奨」とすることにより、この問題は解決されます。Java では、非推奨のための 2 つの機構がサポートされています。1 つは注釈 (J2SE 5.0 からサポートされるようになった) で、もう 1 つは Javadoc タグ (バージョン 1.1 以来サポートされている) です。 古い API に対する既存の呼び出しも引き続き機能しますが、注釈により、コンパイラは非推奨のプログラム要素を参照している箇所を見つけたときに警告を発行します。 Javadoc タグとそれに関連したコメントは、非推奨の項目を使用しないようユーザに警告するとともに、代わりに何を使用したらよいかを伝えます。

いつ非推奨とするか

API を設計する際には、その API が古い API に取って代わるものとなるかどうかを注意深く検討します。もし取って代わるものであり、新しい API に移行するよう開発者 (API のユーザ) に推奨する場合には、古い API を非推奨にします。ある API を非推奨にする適切な理由としては、次のようなことが考えられます。

上記のいずれの場合にも、非推奨という処置は合理的な選択です。新しい API に変更するよう開発者たちを促している間、「下位互換性」が保たれるからです。また、開発者たちがいつ新しい API へ移行するかを決定する助けとして、非推奨になった技術的理由をコメントに簡潔に含めることもできます。

非推奨にするクラスの個別のメンバフィールド (プロパティ) については、あるプロパティについて具体的な説明を加えたい場合を除いて、非推奨タグを付ける必要はありません。

非推奨とする方法

J2SE 5.0 からは、クラス、メソッド、またはフィールドを非推奨にするために、@Deprecated 注釈を使用できるようになりました。さらに、Javadoc の中でプログラム要素に非推奨のマークを付け、非推奨 API の使用を回避する方法を開発者に伝えるために、@deprecated Javadoc タグを使用することもできます。

注釈を使用すると、コンパイラは非推奨のクラス、メソッド、またはフィールドが使用されている場合に警告を生成します。ただし、非推奨のコンパイル ユニットの中で非推奨のクラス、メソッド、またはフィールドが使用されている場合には、コンパイラは非推奨警告を表示しません。これにより、従来の API をビルドする場合に、警告が生成されることを防ぎます。

Javadoc の @deprecated タグを使用するときは、新しい API の使用方法を説明したコメントを添えることを強くお勧めします。これは、開発者が古い API から新しい API への効果的な移行方法を決定する助けになります。詳細については、「@Deprecated Javadoc タグの使用」 を参照してください。

注 - Java 言語仕様では、@Deprecated 注釈でマークされたクラス、メソッド、またはフィールドが使用されたときには、コンパイラが警告を発行するよう定められています。一方、@deprecated Javadoc タグでマークされたクラス、メソッド、またはフィールドが使用されたときにコンパイラが警告を発行するべきことは Java 言語仕様では定められていません。もっとも、現行の Sun コンパイラでは、このタグが使用されている場合でも警告は発行されます。ただし、今後も Sun のコンパイラでこのような警告を発行するという保証はありません。

@Deprecated 注釈の使用

J2SE 5.0 では、注釈 (メタデータともいう) と呼ばれる新しい言語機能が導入されました。Java 言語の組み込み注釈の 1 つに @Deprecated 注釈があります。この注釈を使用するには、クラス、メソッド、またはメンバの宣言の前に「@Deprecated」を置くだけです。

@Deprecated 注釈を使用すると、クラス、メソッド、またはフィールドが非推奨になり、コード内でそのプログラム要素が使用されている場合に、すべてのコンパイラで警告 が発行されます。それに対して、@deprecated Javadoc タグを使用した場合は、すべてのコンパイラでそのタグに基づいて警告が発行されるとは限りません。現行の Sun のコンパイラでは、このタグが使用されている場合でも警告は発行されますが、他のコンパイラでは警告が発行されない可能性があります。したがって、@Deprecated 注釈を使用すれば、@deprecated Javadoc タグを使用する場合よりも、警告の生成という面で移植性が高くなります。

注: 非推奨はクラスや個々のメソッドまたはプロパティに適用されるものであって、それらのプログラム要素の名前に適用されるものではありません。1 つのメソッドが、非推奨と「非推奨でない」オーバーロードの両方を持つことも可能です。また、「非推奨でない」プロパティが非推奨メンバを隠したりオー バーライドすることにより、非推奨を外すことも可能です。あるメソッドを非推奨にする必要がある場合、そのメソッドのオーバーライドを非推奨にすることは API の開発者の責任です。

次に示すのは @Deprecated 注釈の簡単な使用例で、java.lang.Thread からの抜粋です。

public
class Thread implements Runnable {
...
@Deprecated
public final void stop() {
synchronized (this) {
...

@deprecated Javadoc タグの使用

@deprecated タグを使用すると、Javdoc により、あるプログラム要素が非推奨であることを明記させることができます。@deprecated タグの後にはスペースまたは改行を置く必要があります。@deprecated タグに続く段落では、その項目が非推奨になった理由と、その使用を避ける方法について説明します。

JavaDoc は、@deprecated に基づいて、特別な HTML を生成します。まず、@deprecated タグに続く段落を説明の前に移動してイタリック体で表示し、その直前に「注: foo は推奨されません。 」という警告を太字で表示します。Javadoc はまた、非推奨項目を示すインデックスのエントリに対して「推奨されません。」と太字で表示します。

このタグを付けた段落に何も記述しないことも可能ですが、非推奨を示す段落を空白にするのは望ましくありません。何も記述されていないと、非推奨の 機能を使用した場合に発行される警告にユーザが対処できないからです。 また、同じ機能を備えた新バージョンを参照する @link タグまたは @see タグを段落に含めるようにしてください。非推奨 API の段階的廃止の予定期日を具体的に説明するのは適切ではありません。これは、他の方法で伝達するべきビジネス上の決定だからです。

@deprecated Javadoc タグの使用方法の詳細については、「javadoc - Java API ドキュメントジェネレータ」および「How to Write Doc Comments for the Javadoc Tool」を参照してください。

このあとの例はそれぞれ、@deprecated Javadoc タグの使用方法を示しています。また、@Deprecated 注釈の使用例も含まれており、この 2 つを一緒に使用するべきであることを強調しています。

次の例は、非推奨メソッドのもっとも一般的な記述方法です (Javadoc 1.2 以降の場合)。

/**
* @deprecated As of release 3.1, replaced by {@link #getPreferredSize()}
*/
@Deprecated public Dimension preferredSize() {
return getPreferredSize();
}

注 - javadoc 1.1 の場合は、標準的な記述方法が上記と異なります。「How to Write Doc Comments for the Javadoc Tool」を参照してください。

非推奨の理由が単に名前の変更であれば、「このメソッドは getPreferredSize によって置き換えられました」といった記述は不要です。@link タグによってその置き換えをユーザに明示しているからです。

API の再編成が単なる名前の変更以上のものである場合は、非推奨の説明はもう少し複雑になります。次の例は、廃止になるメソッドについての説明です。

/**
* Delete multiple items from the list.
*
* @deprecated Not for public use in the future.
* This method is expected to be retained only as a package
* private method.
* {@link #remove(int)}
* {@link #removeAll()}
*/
@Deprecated public synchronized void delItems(int start, int end) {
...
}