The King's Museum

ソフトウェアエンジニアのブログ。

Effective Java

【Effective Java】項目55:注意して最適化する

最適化に関してはさまざまな格言があります。 特に知られているのは Knuth によるものでしょう。*1 僅かな効率、たとえば、時間の約97%、については忘れるべきである。時期尚早の最適化は、すべての悪の根源である。 速いプログラムを書くことよりも、良…

【Effective Java】項目54:ネイティブメソッドを注意して使用する

Java Native Interface (JNI) を使うと C/C++ などで書かれたネイティブメソッドを呼び出すことができます。 歴史的にネイティブメソッドには3つの用途がありました。 レジストリ、ファイルロックなどのプラットフォーム固有機構へのアクセス 古いコードのラ…

【Effective Java】項目53:リフレクションよりインタフェースを選ぶ

リフレクション機構 リフレクション機構を使うと、ロードされたクラスの情報に、プログラムからアクセスすることができます。 具体的には Class インスタンスに対して、それが表すクラスのコンストラクタ・メソッド・フィールドを取得することができます。 …

【Effective Java】項目52:インタフェースでオブジェクトを参照する

適切なインタフェース型が存在するのであれば、パラメータ、戻り値、変数、フィールドではすべてインタフェース型を利用して宣言するべきです。 オブジェクトのクラス名を参照する必要がある唯一の箇所は、そのオブジェクトを生成するところです。 // 良い例…

【Effective Java】項目51:文字列結合のパフォーマンスに用心する

文字列の結合演算子(+)は文字列を結合するための便利な演算です。 しかし、これを利用する場合にはパフォーマンスに注意する必要があります。 Java の文字列(String)は不変です。 そのため、2つの文字列が連結される時、2つの文字列をコピーして連結…

【Effective Java】項目50:他の型が適切な場所では、文字列を避ける

文字列は文字列以外の場所で使うべきではありません。 例えば文字列を値の代わりに使うことは避けるべきです。 一般的に入力パラメータは文字列ですが、適切な型がある場合はパラメータをその型に変換するべきです。 int や boolean として扱えるパラメータ…

【Effective Java】項目49:ボクシングされた基本データより基本データを選ぶ

『基本データ』と『ボクシングされた基本データ』 Java では int などの基本データ型(primitive type)と、String などの参照型(reference type)の2つの型があります。 int や double の基本データ型は、それぞれに対応するボクシングされた基本データ(b…

【Effective Java】項目48:正確な答えが必要ならば、float と double を避ける

浮動小数点数 数値に関する正確な答えが知りたい場合、float と double の利用は避けるべきです。 float と double は2進数浮動小数点数で表されます。 浮動小数点数は広い範囲の数値計算に対して、近似をすばやく行うために設計された小数計算方式です。 …

【Effective Java】項目47:ライブラリーを知り、ライブラリーを使う

標準ライブラリーの利点 標準ライブラリーを使うことには大きなメリットがたくさんあります。 第一に自作ライブラリと比較して、標準ライブラリは非常に完成度が高いです。 高度なバックグラウンドをもったシニアエンジニアが設計、実装、テストを行っていま…

【Effective Java】項目46:従来の for ループより for-each を選ぶ

for ループよりも for-each ループを利用しましょう。 Java 5 よりも前では、コレクションと配列を走査する好ましい方法は以下の通りでした。 // コレクションの走査 for (Iterator i = c.iterator; i.haxNext(); ) { doSomething((Element) i.next()); } //…

【Effective Java】項目45:ローカル変数のスコープを最小限にする

ローカル変数のスコープは最小限にするべきです。 Java では古いバージョンの C 言語と違って、文が書ける場所であれば変数宣言を書くことができます。 スコープの先頭ですべての変数を宣言せず必要な箇所で変数を宣言すれば、変数のスコープを最低限に保て…

【Effective Java】項目44:すべての公開 API 要素に対してドキュメントコメントを書く

Javadoc Javadoc はソースコードに書いたドキュメンテーションコメントを処理して、ソースコードから自動的に API ドキュメンテーションを生成することができます。 Javadoc のドキュメントコメント規約は Java の一部ではありませんが、事実上の API となっ…

【Effective Java】項目43:null ではなく空配列か空コレクションを返す

配列やコレクションを返すメソッドは、null を返すべきではありません。 null の代わりに空の配列か空のコレクションを返すべきです。 null を返すとメソッドを利用するコードには null チェックが必要になるため、コードが煩雑になります。 そこで null チ…

【Effective Java】項目42:可変長引数を注意して使用する

可変引数メソッド Java 5 から可変長引数メソッドが利用できるようになりました。 正式には『可変引数メソッド(variable arity method)』と呼ばれています。 可変引数メソッドは任意の0個以上の引数を受け付けることができます。 実際の動作は次のとおり…

【Effective Java】項目41:オーバーロードを注意して利用する

オーバーロード オーバーロードとは同じ名前・同じ数の引数を持つメソッドに対して、呼び出し側の引数に応じて、対応するメソッドが呼び出される機能のことです。 たとえば、引数の型ごとに型の名前を返すメソッドをオーバーロードを使って実装します。 publ…

【Effective Java】項目40:メソッドのシグニチャを注意深く設計する

ここでは独立して項目を作るほどではないような API 設計時のヒントを説明します。 メソッド名を注意深く選ぶ メソッドに限らず名前は常に標準命名規約に従うべきです。 理解可能で同じパッケージの他の名前と矛盾しない内容にするべきです。 さらに、一般的…

【Effective Java】項目39:必要な場合は、防御的にコピーする

不変オブジェクトの抜け道 クラスの製作者は常に「クライアントは不変式を破壊するためにあらゆる方法を使ってくる」と仮定し、防御的にプログラムを書くべきです。 「セキュリティホールをついてくるような悪意のある開発者」から「単純な間違いをおかす初…

【Effective Java】項目38:パラメータの正当性を検査する

第6章が終わったので『第7章:メソッド』に入る。 この章は一般的な話なのですぐに終わりそうだ。 パラメータをチェックする ほとんどのメソッドとコンストラクタは、渡されるパラメータに関して何らかの制限を持っています。 この制約は文書化し、メソッ…

【Effective Java】項目37:型を定義するためにマーカーインタフェースを使用する

マーカーインタフェース マーカーインタフェースはメソッド宣言を一つももたないインタフェースです。 そのインタフェースを実装しているクラスが何か特別な性質を持っていることを示すために宣言します。 たとえば Serializable インタフェースはマーカーイ…

【Effective Java】項目36:常に Override アノテーションを利用する

@Override アノテーション Java 1.5 でいくつかのアノテーションがライブラリに追加されましたが、最も重要なのは @Override アノテーションです。 @Override アノテーションはスーパークラスのメソッドをオーバーライドしていることを示します。 public cla…

【Effective Java】項目35:命名パターンよりアノテーションを選ぶ

アノテーション Java のアノテーションは、ソースコードにメタデータを付与するための仕組みです。 付与されたアノテーションは、コンパイル時にコンパイラが利用したり、実行時に仮想マシンが利用したりします。 通常、アノテーションはメタデータなのでコ…

【Effective Java】項目34:拡張可能な enum をインタフェースで模倣する

Enum の疑似拡張 Java の Enum 型は拡張することはできません。 たとえ可能だとしても拡張するべきではありません。 ただし、拡張可能な Enum を利用したくなる場合があります。 オペコードと呼ばれるマシンに対する操作を列挙型で表現したいとします。 その…

【Effective Java】項目33:序数インデックスの代わりに EnumMap を使用する

序数インデックス 配列のインデックスとして Enum の ordinal() を使ってはいけません。 例えばハーブの種類(一年生(Annual)、多年生(Perennial)、越年生(Biennial))ごとに、ハーブをまとめたいと仮定します。 このような場合、配列と Enum.ordninal…

【Effective Java】項目32:ビットフィールドの代わりに EnumSet を使用する

ビットフィールド 列挙型を集合として用いる場合、旧来は以下の方法が使われました。 public class Text { public static final int STYLE_BOLD = 1 << 0; // 1 public static final int STYLE_ITALIC = 1 << 1; // 2 public static final int STYLE_UNDERLI…

【Effective Java】項目31:序数の代わりにインスタンスフィールドを利用する

ordinal() メソッド enum は ordinal() というメソッドを持っています。 これは列挙宣言での位置を返すメソッドです。 public enum Week { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday; } Week.Sunday.ordinal(); // => 0 Week.Monday.…

【Effective Java】項目30:int 定数の代わりに enum を使用する

「第6章 enum とアノテーション」に入った。 int/string enum パターン 列挙型は固定数の定数から成り立つ型です。 Java に enum 型が追加される前、列挙型を実現するためには int enum パターンと呼ばれるパターンを利用しました。 // int enum パターン p…

【Java・ジェネリックス】ワイルドカード型とは何か【後半】

Java のジェネリックスにあるワイルドカードについて解説するシリーズの後半。 非境界ワイルドカード型と原型 前回、ワイルドカードの中でも特に「非境界ワイルドカード型」について説明しました。 非境界ワイルドカード型は「ジェネリックスを利用したいけ…

【Java・ジェネリックス】ワイルドカード型とは何か【前半】

Java のジェネリックスにあるワイルドカードについて解説するシリーズの前半。 ワイルドカード型 ワイルドカード型とは型パラメータに ? の記号が書かれているジェネリックス型のことを指します。 ワイルドカード型には「非境界ワイルドカード型」と「境界ワ…

【Effective Java】項目29:型安全な異種コンテナーを検討する

今回は「型安全な異種コンテナーを検討する」だ。 ジェネリックスの章の最後の項目だけあって比較的発展的な内容。 異種コンテナー 通常、ジェネリックスは Set<Integer> や List<String> のように、特定の型の要素を持つコンテナーに対して利用します。 List<String> list = new Arra</string></string></integer>…

【Effective Java】項目28:API の柔軟性向上のために境界ワイルドカードを使用する(その2)

今回は「項目28:API の柔軟性向上のために境界ワイルドカードを使用する」の後半。 明示的型パラメータ 前回の記事では境界ワイルドカード型について説明しました。 そして、それを利用することで API の柔軟性が向上することについて述べました。 今回は…

(c) The King's Museum