Javaの文法

Javaの文法の記事では、プログラミング言語Javaの構文について解説する。また、それ以外についても解説している。

__TOC__

1. キーワード一覧
----------

Javaの基本言語仕様は54種類程度に抑えたキーワードによって比較的コンパクトにまとめられている。Javaの構文はC++言語によく似たものであり、それよりも比較的平易化されている。従って以下のキーワードを眺めるだけでもJavaプログラミングの大まかなスタイルを掴むことができる。



2. データ型
-------

Javaのデータ型には大別して、プリミティブ型と参照型がある。

2.1. プリミティブ型
------------

enもしくはenとも。 プリミティブ型はオブジェクトではなく、スーパークラスを持たない。

 注:
オーバフローは例外等にはならず、2の補数として自然な形でラップアラウンド  する。例えば、name=Integer.MAX_VALUE  に1を加えると、結果はname=Integer.MIN_VALUE  になる。 float f = 2147483647f; double d = 9223372036854775807;float型は数字を符号付き32Bitの最大値まで代入できるが、double型は符号付き64Bitの最大値まで代入できる。

また、float型は代入する数字の末尾に「F」または「f」をつけなければdouble型とみなされ、コンパイルエラーになってしまう。

注
浮動小数点数は決して例外をスローしない
0でない値を0で割った値はInfと等値である
無限大でない値をInfで割った値は0と等値である。 注:
J2SE v 1.4.2までのcharは基本多言語面  の範囲内のコードポイントを符号無し16ビットで表現する。
J2SE 5.0からは、補助文字をサポートするため、charは符号無し16ビットで表現可能でありBMPの範囲内に限ればコードポイントと同値となるUTF-16符号化形式のコード単位を表現するように変更され、21ビットが必要となるコードポイントの表現にはintを使用するように変更された。つまりchar型は互換性の問題からあくまで符号無し16ビットのままとされており、UTF-16符号化形式を採用したことから補助文字を扱う場合はコードポイント一つにコード単位を格納したchar値のペアが対応する。これらを適切に取り扱う便宜として、java/langクラスやプリミティブラッパークラスであるjava/langクラスなどの各種メソッドが利用できる。 注:
C/C++や類似の言語と異なり、Javaではfalseの代わりに0またはnullと書くことはできない
同様に、0でない値を書いてtrueの代わりとすることはできない
ブール型をブール型でない基本型へキャストすることとその逆はできない

2.2. 参照型
--------

すべての参照型はオブジェクト型を表すクラスjava/langから派生する。オブジェクトは参照型のインスタンスである。クラスclassは既定でjava/langから派生する参照型である。列挙型enumは抽象クラスjava/langから暗黙的に派生する参照型である。

リフレクション機能のための「クラスを表現するクラス」としてjava/langが存在するが、クラス自体はオブジェクトではない。

2.2.1. 文字列
----------

java/langオブジェクトは不変である
Stringオブジェクトは生成時に初期化されなければならない
コンパイラは文字列リテラルを見つけると、Stringオブジェクトを生成する
演算子 + と += は文字列を連結するためにオーバーロードされる String str1 = "alpha"; String str2 = new String;

java/langとjava/langオブジェクトは可変なので、オブジェクト生成オーバヘッド無しで柔軟に文字列を生成・変更できる。StringBufferとStringBuilderの違いは、StringBufferがマルチスレッドに対応しているのに対し、StringBuilderは対応していないことである。
StringとStringBufferは互いに独立であり、一方から派生したものではない StringBuffer str1 = new StringBuffer; str1.append; str1.setCharAt, 'b'); System.out.println; // str1.toString を呼び出す。 // 印字結果は"alpha-beta"となる

2.2.2. プリミティブラッパークラス
--------------------

プリミティブラッパークラス

機能:
ある型の値を他の型へ変換する静的メソッドを提供する
基本型を参照型としてラッピングする目的で使用できる その他:
ブール型以外の基本型の初期値は0。ブール型の初期値はfalse。ラッパークラスの初期値はnull。

2.2.3. 配列
---------

配列自体はオブジェクト型java/langのサブクラスつまり参照型である。
プリミティブ型の配列、オブジェクト型の配列、さらにそれらの配列の配列、などの配列を扱える。
プリミティブ型の配列では、全ての要素はその型の値でなければならない。
オブジェクトの配列では、階層関係にある必要がある。
配列オブジェクトは配列要素の数を表す読み取り専用の属性「length」を持つ。
すべての配列は動的に領域確保される。配列を生成する際の要素数として、定数だけでなく変数を使用することができる。
「配列の配列」ではない、多次元配列は無い。 // 配列を宣言 - 配列名は「myArray」、要素の型は "SomeClass" への参照 SomeClass[] myArray = null;

// 配列を生成 myArray = new SomeClass[10];<WtXmlEndTag />

// または宣言と生成を同時に行う SomeClass[] myArray = new SomeClass[10];

// 配列の要素を割り当てる  for  myArray[i] = new SomeClass;

3. リテラル
-------

リテラルの例を示す。



4. 国際化サポート
----------

Javaは1バイト整数の型と文字の型とを区別する。なお、charは、名前に反して必ずしも文字を表現していない場合があり得る。すなわち、実際にはUCS-2による、いわゆるダブルバイトである。J2SE 5.0以降ではサロゲートAPIによって、サロゲートペアに対応した。

JavaプログラムのソースコードおよびソースファイルはUTF-8でエンコードするのが基本である。Unocodeに対応したエンコードであれば、Javaプログラムのソースコードに直接Unicode文字を記述することもできる。なお、-encodingコンパイルオプションを指定することで、対応する任意のエンコードを使用することもできる。ロケール依存のコードページを利用することもできる。

文字列リテラルやコメントの他、クラス名や変数名も国際化に対応している。例えば、次のソースコードはJavaのコードとして正しく解釈されコンパイルされ実行できる。ここではクラス名、変数名、および文字列リテラルとして日本語の文字を使っている。

public class こんにちは世界 { private String 文字列 = "こんにちは世界"; }

5. 演算子
------

5.1. 算術演算子
----------

算術演算子



5.2. 代入演算子
----------

代入演算子



5.3. 関係演算子
----------

関係演算子

関係演算子を参照型に対して用いた場合、そこで比較されるのは参照先のオブジェクトが同じかどうかであり、オブジェクトの中身の値が一致するか否かではない。オブジェクトの中身を比較したい場合はname=Object.equalsメソッドを使用する。instanceof演算子は、オブジェクトが指定クラスのインスタンスであるか否かを判定するために用いる。

5.4. 三項演算子
----------

三項演算子は二つの記号?と:を組み合わせて記述する。条件演算子とも呼ぶ。構文は以下である。

条件 ? 式1 : 式2

条件がtrueであるとき、式1の値をとる。そうでない場合は式2の値をとる。

例: String answer =  ? "reject": "keep";

// これは以下のコードと等価である: String answer; if  { answer = "reject"; } else { answer = "keep"; }

5.5. 論理演算子
----------

論理演算子

短絡評価論理演算 
必要最小限の式しか評価しない
部分的な評価 

5.6. ビット演算子
-----------

ビット演算子



5.7. 文字列演算子
-----------



6. 制御構造
-------

6.1. if... else
---------------

if文 if  {//statements//; } else if  {//statements//; } else {//statements//; }

//expr//は真偽値を与えなければならない。

6.2. switch文
------------

switch文 switch  { case VALUE1:statement11 ; … ; statement1L ; break ; case VALUE2:statement21 ; … ; statement2M ; break ; default:statementd1 ; … ; statementdN ; }

expr 値の型はbyte/short/int/charあるいはそれらのプリミティブラッパークラスでなければならない。
J2SE 5.0以降では列挙型  を、JavaSE 7以降ではString型を使用することもできる。caseラベルの値にnullは使用できない。
各々のcaseラベルの値はユニークなリテラル、あるいはコンパイル時に値が定まる定数式  でなければならず、変数を書くことはできない。

6.3. forループ
-----------

for文 for  {//statements//; }

6.3.1. for-each ループ
-------------------

J2SE 5.0では、for-each文と呼ばれる新機能が追加された。これは集合の中の全要素を順番に参照するような処理を大いに簡素化する。このような場合、従来は次の例に示すような反復子  を書かねばならなかった: // Java 5.0以前にはジェネリクスもないため、実際にはさらに煩雑となる。 public int sumLength { int sum = 0; Iterator itr = stringSet.iterator; while ) { sum += itr.next.length; } return sum; }

for-each文はこのメソッドを大いに簡素化する:

public int sumLength { int sum = 0; for  { sum += s.length; } return sum; } この例の動作としては、stringSetに含まれる全てのjava/langについて、長さを取得してsumに加算する。

6.4. whileループ
-------------

while文

while  {//statements//; }

6.5. do ... while
-----------------

do-while文 do {//statements//; } while ;

6.6. 分岐命令
---------



6.6.1. 例
--------

int sum = 0; for  { if  { continue; // このループの残りをスキップしforに戻る。 } sum += i;

if  { break; // ループを脱出する。 } }<WtXmlEndTag />

6.7. ラベル
--------

末尾にコロンがついた識別子からなる。
分岐命令が参照する文またはブロックを識別するために使われる。
仮にラベルを外したとすると、分岐命令は最も内側のループについて機能する。例://LABEL1//: //statement//;//LABEL2//: { //statements//; }

6.8. goto
---------

Javaのキーワードには「goto」という綴りも含まれているが、goto文は無い。

7. オブジェクト
---------

7.1. クラス
--------

Javaではクラスあるいはインタフェースの内部で別のクラスを宣言することができる。これは「ネストされたクラス」 と呼ばれる。ネストされていないクラスは「トップレベルクラス」 と呼ばれる。ネストされたクラスがstatic修飾されていない場合、「内部クラス」 となる。内部クラスは外側のクラスのインスタンスを暗黙的にキャプチャすることで、静的メンバ、非静的メンバいずれにもアクセスすることができる。ネストされたクラスがstatic修飾されている場合、「静的クラス」 となり、静的メンバのみにアクセスできる。メソッドの内部にクラスを定義することもでき、これは「ローカルクラス」 と呼ばれる。ローカルクラスでは、外側のローカル変数には読み取りアクセスのみできる。また、型の名前を持たないローカルクラスとして「匿名クラス」 を定義し、同時にインスタンス生成をすることもできる。

クラスあるいはインタフェースの内部で別のインタフェースを宣言することもできる。これは「ネストされたインタフェース」と呼ばれる。

クラスを宣言する際は以下の修飾子を付けることができる:

abstract – インスタンス化できない。インタフェースとabstract  クラスだけがabstract  メソッドを持つことができる。抽象クラスを継承する具象  サブクラスは、引き継がれた全ての抽象メソッドを、abstractでないメソッドでオーバーライドしなければならない。修飾子finalと併用することはできない。
final – サブクラスを作らせない。 finalクラスのすべてのメソッドは無条件にfinalになる。 修飾子abstractと併用することはできない。
strictfp – このクラスとそこに含まれる全てのネストクラスにおいて、全ての浮動小数点演算は厳密な浮動小数点演算動作を使用する。厳密な浮動小数点演算動作は、演算結果がプラットフォームに関わりなく同一となることを保証する。Javaのクラス定義ブロックはセミコロン;で終わらせる必要はない点に注意。この点はC++の文法と異なる。

7.1.1. 継承
---------

// 子クラスは親クラスを継承する class ChildClass extends ParentClass { ... }

任意のクラスのデフォルトの親クラスはObjectクラスである。
クラスは単一の親クラスだけを継承できる。実装多重継承はできない。

7.1.2. スコープ
-----------

this – 現在のサブクラス  への参照 )。
super – 親クラスへの参照 )。サブクラスがオーバライドした親クラスのメソッドや、サブクラスが継承しつつも隠蔽した親クラスのフィールドにアクセスするために使うことができる。

7.2. インタフェース
------------

インタフェースとは、実装の詳細がいっさいない抽象型である。その目的は複数のクラスを多態性によって統一的に扱うことである。共通のインタフェースを実装する複数のクラスは、そのインタフェース型のコンテキストにしたがって互いに交換可能とすることができる。インタフェースはまた、抽象化 – クラスの実装方法を隠蔽すること – という考え方を強制するのにも役立つ。

インタフェースは抽象メソッドと定数フィールド  だけを含むことができる。インタフェースメソッドはデフォルトでpublicかつabstractであり、インタフェースフィールドはデフォルトで public static final である。インスタンスフィールドやクラスフィールドすなわち状態を持つことができない点が抽象クラスと異なる。

Javaは完全な直交の多重継承はサポートしておらず、インタフェースによる「型の多重継承」のみをサポートする。C++における多重継承には、複数の親クラスや型から複数回継承したフィールドやメソッドを識別するための複雑なルールが伴う。インタフェースを実装から分離することにより、インタフェースはより単純かつ明快に多重継承が持つ利点の多くを提供する。もっとも、実装の多重継承を避ける代価としてコードは若干冗長になる。というのは、インタフェースはクラスのシグネチャを定義するのみで実装を持てないため、インタフェースを継承する全てのクラスは定義されたメソッドをいちいち実装しなければならないからである。純粋な多重継承であれば実装自体も継承されるのでこのようなことはない。

なお、Java 8ではインタフェースのデフォルトメソッドにより実装の多重継承を限定的にサポートするようになった。また、インタフェースが静的メソッドを持つこともできるようになった。

Javaのインタフェースは Objective-C規約のコンセプトによく似た振る舞いをする。

7.2.1. インタフェースの実装
-----------------

クラスは、一つのクラスを継承できるのに加えて、implementsキーワードを用いて一つ以上のインタフェースを実装することができる。 interface MyInterface { void foo; }

interface Interface2 { void bar; }

class MyClass implements MyInterface { void foo {...} ... }

class ChildClass extends ParentClass implements MyInterface, Interface2 { void foo {...} void bar; ... }<WtXmlEndTag />

以下の例では、Deleteableインタフェースを実装する非abstractクラスは、引数無しで戻り型がvoidであるdeleteという名前の非抽象メソッドを定義しなければならない。そのメソッドの実装と機能は各々のクラスによって決定される。

public interface Deleteable { void delete; }

このコンセプトにはさまざまな使い道がある。例えば:

public class Fred implements Deleteable { // このメソッドはDeleteableインタフェースを満足する public void delete { // ここにコードを実装 } public void someOtherMethod { } }

public void deleteAll { for  { list[i].delete; } }<WtXmlEndTag />

上の配列に含まれる全てのオブジェクトはdeleteメソッドを持つことが保証されるので、deleteAllメソッドはFredオブジェクトと他の如何なるDeleteableオブジェクトをも区別する必要がない。

7.2.2. インタフェースの継承
-----------------

インタフェースはextendsキーワードを用いて一つ以上のインタフェースを継承することができる。

interface ChildInterface extends ParentInterface, AnotherInterface { ... }

結果として生じるインタフェースを実装するクラスは、元のインタフェースに含まれたメソッドをも併せて定義しなければならない。

public interface MyInterface { foo; }

public interface Interface2 extends MyInterface { bar; }

public class MyClass implements Interface2 { void foo {...} void bar {...} ... }<WtXmlEndTag />

7.3. アクセス修飾子
------------

アクセス修飾子は、そのクラスやクラスメンバにアクセス可能なクラスを決定する。

7.3.1. トップレベルクラスアクセス
--------------------

デフォルトでは、Javaのクラスは、それら自身のJavaパッケージからのみアクセスできる。これは、クラスのパッケージが、裏に隠れて機能を実行するようなＡＰＩを提供することを可能とする。外にアクセスを公開されたクラスの動作を、隠されたクラスが支える形になる。

デフォルト  – 定義されたパッケージ内からのみアクセス可能。
public – 定義されたパッケージの外のクラスからもアクセス可能。

7.3.2. クラスメンバアクセス
-----------------

//クラスメンバ//とはフィールド、メソッド、コンストラクタ、クラス内で定義されたネストされたクラスのことである。アクセス制限が厳しいものから並べると、クラスメンバのアクセス修飾子は次の通り。

private – そのクラスからのみアクセス可能 。private宣言されたメンバはサブクラスによって引き継ぐことができない。
package-private  – 同じパッケージ内の他クラスからもアクセス可能。
protected – 上に加え、パッケージ外の継承クラスからアクセス可能。
public – 任意のクラスからアクセス可能。メソッドをオーバライドする際、そのメソッドのアクセス権を「より厳しく」することはできない。さもなくば親クラスのインタフェース契約を壊してしまうからである。したがってオーバライドされる場合、publicメソッドはpublicとして宣言されねばならず、protectedメソッドをデフォルトアクセス権とすることはできない。しかしながら、メソッドをオーバライドしてアクセス権を「より緩める」ことは許される。したがってオーバライドする際、デフォルト  アクセス権のメソッドはprotectedまたはpublicとして宣言することができ、protectedメソッドはpublicとして宣言することができる。

7.4. フィールド
----------

アクセス修飾子に加えて、データフィールドは以下の修飾子によって宣言される:

final – このフィールドの中身は変更できない。ただ一度のみ値を設定できる。イニシャライザ  がないfinalフィールドを「ブランクfinal」フィールドと呼ぶ。staticなブランクfinalフィールドは最終的にスタティックイニシャライザによって初期化されなければならない。staticでないブランクfinalフィールドはコンストラクタの実行中に必ず初期化されなければならない。volatileにはなれない。
static – クラスのインスタンスではなくクラスに属する。
transient – オブジェクトの中でも永続的  にできないフィールドである。このフィールドの中身を待避または復元してはならないことをコンパイラに知らせる。
volatile – そのフィールドが他スレッドによって非同期にアクセスされる可能性があることをコンパイラに知らせる。finalにはなれない。

7.4.1. 定数
---------

staticとfinal両方を宣言されたフィールドは事実上、定数である。staticはそのフィールドがそのクラスにおいてただ一つのみ存在することを示し、finalはそのフィールドがただ一度のみ値を設定可能であることを意味する。

7.5. 初期化子
---------

「イニシャライザ」はフィールドのイニシャライザと同時に実行されるコードのブロックである。

7.5.1. 静的初期化子
-------------

「スタティックイニシャライザ」はstaticフィールドのイニシャライザと同時に実行されるコードのブロックである。静的フィールド初期化子と静的初期化子は宣言された順番に実行される。静的初期化はクラスがロードされた後で実行される。

static int count = 20; static int[] squares; static { // スタティックイニシャライザ squares = new int[count]; for  squares[i] = i * i; } static int x = squares[5]; // x には値25が代入される。

7.5.2. インスタンス初期化子
-----------------

「インスタンスイニシャライザ」はインスタンスの  フィールドの初期化子と同時に実行されるコードのブロックである。インスタンスフィールド初期化子とインスタンス初期化子は宣言された順番に実行される。

インスタンス初期化子とインスタンスフィールド初期化子はコンストラクタが呼び出された際に実行される。正確な実行順序としては、親クラスのコンストラクタが実行された後、かつ、自身のコンストラクタが実行される前、となる。

7.6. メソッド
---------

アクセス修飾子に加えて、メソッドには以下の修飾子を付けて宣言できる：

abstract – 当該クラスでは定義されないメソッドであり、代わりに当該クラスの全ての具象  サブクラスによって定義されなければならない。static、final、nativeのいずれとも併用できない。
final – サブクラスによって再定義できないメソッド。そのメソッドがインスタンス  メソッドでありかつ十分小さいならば、コンパイラはそのメソッドをインライン関数のように各所に展開する場合がある。abstractと併用はできない。
native – このメソッドはネイティブなマシン依存コードにリンクする。メソッド本体無しで宣言される。abstractと併用はできない。Java Native Interfaceにて使用される。
static – クラスのインタンスではなく、クラスに属する。abstractと併用はできない。
strictfp – メソッドとそこに含まれる内部クラス全てにおける浮動小数点演算が、厳密な浮動小数点演算動作を使用する。厳密な浮動小数点演算動作は、演算結果がプラットフォームに関わりなく同一となることを保証する。
synchronized – メソッド本体を実行する前に、関連オブジェクトを排他する。関連オブジェクトが他スレッドにて排他済である場合、他スレッドが排他を解除し自スレッドが排他を獲得するまで実行を待たされる。ここで言う関連オブジェクトとは、そのメソッドがstaticならばjava/langオブジェクトを指し、非staticならばオブジェクトインスタンスを指す。abstractメソッドをsynchronizedとして宣言することは可能だが意味はない。何故なら排他とは宣言ではなく実装に伴う機能であり、抽象メソッドは実装を持たないからである。privateメソッドは自ずからfinalであり、abstractにはできない点に注意。

7.6.1. 可変引数
-----------

Java SE 5.0において、引数の個数が可変であるようなメソッドについての文法上の便宜  [1]が追加された。これによって引数の個数が可変であるメソッドをタイプセーフに使用することが容易になる。最後のパラメタの後に「...」と書くと、Javaは全ての引数を配列に格納する：

public void drawPolygon { /* ... */ }

このメソッドを呼ぶ際、プログラマは個々のpointsを単にカンマで区切って書けばよく、java/awtオブジェクトの配列をわざわざ用意する必要はない。このメソッドの内部でpointsを参照する際はpoints[0]、points[1]、などのように書ける。pointsが渡されていない場合、配列のlengthは0となる。可変個の引数と別に固定的に必要なパラメタがある場合は、それらのパラメタは可変引数に先立って指定すればよい。

// ポリゴンは少なくとも3つの点を必要とする。 public void drawPolygon { /* ... */ }

7.7. コンストラクタ
------------

コンストラクタはオブジェクトが割り当てられた後すぐに呼び出され、オブジェクトの初期処理を行う。コンストラクタは典型的にはnewキーワードを使用して呼び出されるが、リフレクションを使用して呼ぶこともできる。リフレクション機能はjava.lang.reflectパッケージより提供される。

コンストラクタを宣言する際に使える修飾子はアクセス修飾子のみである。

可能ならば、オブジェクトはひとたびコンストラクタを呼ばれた以後は直ちに有効かつ有意味なオブジェクトとなるべきである。分割された複数の初期化用メソッドを使わなければ初期処理が完了しないというような設計は好ましくない。
慣習として、引数としてそのオブジェクト自身の型を受け取ってデータメンバを複写するようなコンストラクタを「コピーコンストラクタ」と呼ぶ。
コンストラクタが明示的に定義されていない場合、コンパイラは暗黙のうちに内容が空で引数を取らないデフォルトのコンストラクタを生成する。
コンストラクタはオーバーロードできる。
コンストラクタ内の最初の文は親クラスのコンストラクタ：super;または同じクラス内の別のコンストラクタ：this;を呼び出せる。
もし、super または thisに対する明示的な呼び出しがないならば、コンストラクタ本体が実行される前に、親クラスのデフォルトコンストラクタsuper;が呼ばれる。

7.8. Objectクラスのメソッド
-------------------

java/langクラスのメソッドは継承されるので、全てのクラスにて使用できる。

7.8.1. cloneメソッド
----------------

name=Object.cloneメソッドは現在のオブジェクトのコピーである新しいオブジェクトを返す。クラスは、それがクローンできることを明示するためにマーカーインタフェースjava/langを実装しなければならない。

7.8.2. equalsメソッド
-----------------

name=Object.equalsメソッドはそのオブジェクトともう一つのオブジェクトを比較し、二つのオブジェクトが同一かどうかをboolean型の値で返す。意味的には、このメソッドはオブジェクトの内容を比較するのに対し、関係演算子"=="はオブジェクトの参照を比較する。equalsメソッドはjava/utilパッケージにあるデータ構造クラスの多くで使われる。これらのデータ構造クラスのいくつかはObject.hashCodeメソッドにも依存している - equalsとhashCodeとの間の契約の詳細について、hashCodeメソッドを参照のこと。

7.8.3. finalizeメソッド
-------------------

name=Object.finalizeメソッドはガベージコレクタがオブジェクトのメモリを解放する前に必ず一度だけ呼び出される。オブジェクトが消滅する前に実行しなければならない何らかの後処理がある場合、各クラスはfinalizeをオーバーライドすることができる。とはいえほとんどのオブジェクトはfinalizeをわざわざオーバーライドする必要はない。

finalizeメソッドがいつ呼ばれるかは保証されない。複数のオブジェクトのfinalizeがどのような順番で呼ばれるかも不定である。もしJVMがガベージコレクションを実行せずに終了するならば、OSがオブジェクトを解放する可能性があり、その場合finalizeメソッドは呼ばれない。

finalizeメソッドは、他のクラスから呼ばれるのを防ぐために、常にprotectedとして宣言されるべきである。

protected void finalize throws Throwable { ... }

7.8.4. getClassメソッド
-------------------

name=Object.getClassメソッドはオブジェクトをインスタンス化するために使われたクラスのjava/langオブジェクトを返す。このクラスオブジェクトはJavaにおけるリフレクションの基本となる。その他のリフレクション機能はjava.lang.reflectパッケージにて提供される。

7.8.5. hashCodeメソッド
-------------------

name=Object.hashCodeメソッドは連想配列にオブジェクトを保存するための「ハッシュ値」として  整数を返す。java/utilインタフェースを実装するクラスは連想配列を提供しhashCodeメソッドに依存する。hashCodeの良い実装は安定  かつ均等に分布するハッシュ値を返す 。

連想配列はequalsとhashCodeの両メソッドに依存するため、これら二つのメソッドの間では、オブジェクトがMapに挿入される場合に関する或る重要な契約が維持されねばならない：

二つのオブジェクト a と b に関して
a.equals == b.equalsでなければならない。
もしa.equalsがtrueならば、a.hashCode == b.hashCodeでなければならない。この契約を維持するために、equalsメソッドをオーバーライドしたクラスは同時にhashCodeメソッドもオーバーライドし、逆もまた同様として、hashCodeとequalsが常に同じ性質に基づくようにしなければならない。

マップがオブジェクトとの間に有する更なる契約は、ひとたびオブジェクトがマップに挿入されたなら、hashCode と equals両メソッドの結果は以後変わらないということである。したがって、一般にハッシュ関数はオブジェクトの不変な属性に基くように設計するのが良い。

7.8.6. toStringメソッド
-------------------

name=Object.toStringメソッドはオブジェクトの文字列表現をjava/langで返すものである。//メソッドは、オブジェクトが文字列連結演算子のオペランドとして使われたとき、コンパイラによって暗黙のうちに呼び出される。

7.8.7. waitとnotifyスレッドシグナルメソッド
------------------------------

全てのオブジェクトは、そのオブジェクトに関連するスレッドについての二つの待ちリストを持つ。一つの待ちリストはsynchronizedキーワードに伴いオブジェクトをミューテックス排他するために使われる。もしミューテックスが他スレッドによって排他されているならば、自スレッドは排他を待っているスレッドのリストに追加される。もう一つの待ちリストはスレッド間でシグナルを送るためのもので、これはwait、notify、notifyAllの各メソッドを通して使用される。

wait/notifyを用いるとスレッド間での能率的な連携が可能となる。あるスレッドが別スレッドでの処理が終わるのを待ち合わせる必要があるとき、または何らかのイベントが発生するまで待たねばならないとき、スレッドはその実行を一時停止してイベントが発生した際に通知を受け取ることができる。これはポーリングとは対照的である。ポーリングにおいては、スレッドは一定時間スリープしてはフラグや他の状態表示をチェックする処理を繰り返す。ポーリングはスレッドがチェックを繰り返さねばならないという点でより計算コストが掛かる上に、実際にチェックしてみるまでイベント発生を検知できないという意味で鈍感でもある。

7.8.7.1. waitメソッド
-----------------

waitメソッドには三つのオーバーロード版があり、タイムアウト値の指定方法がそれぞれ異なる：name=wait、name=wait、name=waitの三つである。一つ目のメソッドはタイムアウト値が0であり、これはタイムアウトが発生しないことを意味する。二つ目のメソッドはミリ秒単位のタイムアウト値を取る。三つ目のメソッドはナノ秒単位のタイムアウト値を取り、これは1000000 * timeout + nanosとして計算される。

waitを呼んだスレッドは待機状態となり、そのオブジェクトの待ちリストに追加される。そのスレッドは以下の三つのイベントのいずれか一つが起きるまで、オブジェクトの待ちリスト上に留まる：

別のスレッドがそのオブジェクトのnotifyまたはnotifyAllメソッドを呼ぶ (詳細はnotifyメソッド参照）