MS Wordでの否定バーの打ち方

否定バーを書きたい対象の文字列を選択し、[挿入]タブの[数式]をクリックして、新しい数式の入力状態にし、[数式ツール]-[デザイン]タブの[アクセント]からオーバーバーをクリックします。
又は、
[挿入]タブの[数式]をクリックして、新しい数式の入力状態にし、[数式ツール]-[デザイン]タブの[アクセント]からオーバーバーを選んで挿入します。点線の□になっているところにカーソルを移動して A をタイプします。

別の方法は、
あらかじめ日本語入力をオフにして、半角英数の状態で [ALT]+=をタイプして数式の入力状態にして
\overbar[SPACE]A[SPACE]
とタイプします。

カテゴリー: MS Office | コメントする

数学記号の文字コード

⋃ 共通集合 U+22C3
⋂ 合併集合 U+22C2

≦ 以下 U+2266
≧ 以上 U+2267

論理演算の否定バーを文字コードで書く事は出来ない。
MS Wordで否定バーを追加する方法はある。

カテゴリー: HTML詳細 | コメントする

縦書きの…

パラメータを列記する時など
パラメータA,パラメータB,…と書きます。
この場合の…はUnicodeカテゴリの一般句読点U+2026[…]です。

縦書きの場合はUnicodeカテゴリの縦書き系U+FE19[︙]ないし点字文字U+2807[ ⠇]を使います。

カテゴリー: HTML詳細 | コメントする

配列のコピー arraycopy()

配列のコピーを作るメソッドにclone()がありますが、arraycopy()も同じように配列のコピーを作ります。
ただし、構文は
clone()とは異なり
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
ソース配列srcの srcPos から srcPos+length-1 までの位置にある要素を、転送先の配列destの destPos から destPos+length-1 までの位置にそれぞれコピーします。
コピー対象は配列であり、配列要素は基本型及びString型、オブジェクト型ですがコピー元とコピー先の型は同一の物でなければならず、srcPos及びdestPos、lengthは正の値で、コピーされるソース配列の配列要素及び転送先配列の配列要素はそれぞれの配列サイズ内でなければいけません。

まず、配列要素が基本型の場合
int型の配列arrayOrg[]とarrayNew[]を作り、arrayOrgの先頭要素から配列要素の末尾までをarrayNewの先頭から末尾までにコピーします。
9行目で二つの配列変数の内容を比較し、配列変数が同じ配列インスタンスを指しているか否かを確認しています。
次にそれぞれの配列インスタンスの中身が同一かを確認。
その上で、19行目で新しい配列の要素の内容を変更し、その変更がコピー元の配列に影響するか確認し、影響していればシャローコピー、指定なければディープコピーと判断しています。

import java.util.*;

public class IntArrayCopy {
	public static void main(String[] args) {
		
		int[] arrayOrg = { 10, 20 };
		int[] arrayNew = new int[2];
		System.arraycopy(arrayOrg, 0, arrayNew, 0, arrayOrg.length);
		System.out.println("arrayOrg:" + arrayOrg + " arrayNew:" + arrayNew);
		if (arrayOrg == arrayNew) {
            System.out.println("arrayOrg == arrayNew");
        } else {
            System.out.println("arrayOrg != arrayNew");
        }
        if (Arrays.equals(arrayOrg, arrayNew)) {
            System.out.println("arrayOrg[] equals arrayNew[]");
        } else {
            System.out.println("arrayOrg[] not equals arrayNew[]");
        }
        arrayNew[1] = 10;
		System.out.println("\nchange arrayNew[1] = 10");
        for (int i = 0; i < arrayOrg.length; i++) {
            System.out.println("arrayOrg[" + i + "] = " + arrayOrg[i] + "   "
            				+ "arrayNew[" + i + "] = " + arrayNew[i]);
        }
		if(arrayNew[1] == arrayOrg[1]) System.out.println("shallow copy");
		else System.out.println("deep copy");
	}
}

実行結果は、新しい配列が指し示す配列インスタンスはコピー元の配列インスタンスとは異なりますが、配列の内容は同じ。そして、新しい配列の配列要素の内容を一部変えても、その影響はコピー元の配列には影響しない事を示しています。
従って、配列要素が基本型の場合のarraycopy()メソッドはディープコピーで新しい配列を作っています

>java IntArrayCopy
arrayOrg:[I@15db9742 arrayNew:[I@6d06d69c
arrayOrg != arrayNew
arrayOrg[] equals arrayNew[]

change arrayNew[1] = 10
arrayOrg[0] = 10   arrayNew[0] = 10
arrayOrg[1] = 20   arrayNew[1] = 10
deep copy

>

次に、配列要素がString型の場合
6行目で作成する配列をString型に変えて、同じ処理を行います。

import java.util.*;

public class StrArrayCopy {
	public static void main(String[] args) {
		
		String[] arrayOrg = { "A", "B" };
		String[] arrayNew = new String[2];
		System.arraycopy(arrayOrg, 0, arrayNew, 0, arrayOrg.length);
		System.out.println("arrayOrg:" + arrayOrg + " arrayNew:" + arrayNew);
		if (arrayOrg == arrayNew) {
            System.out.println("arrayOrg == arrayNew");
        } else {
            System.out.println("arrayOrg != arrayNew");
        }
        if (Arrays.equals(arrayOrg, arrayNew)) {
            System.out.println("arrayOrg[] equals arrayNew[]");
        } else {
            System.out.println("arrayOrg[] not equals arrayNew[]");
        }
        arrayNew[1] = "A";
		System.out.println("\nchange arrayNew[1] = A");
        for (int i = 0; i < arrayOrg.length; i++) {
            System.out.println("arrayOrg[" + i + "] = " + arrayOrg[i] + "   "
            				+ "arrayNew[" + i + "] = " + arrayNew[i]);
        }
		if(arrayNew[1].equals(arrayOrg[1])) System.out.println("shallow copy");
		else System.out.println("deep copy");
	}
}

結果は同じく、新しい配列が指し示す配列インスタンスはコピー元の配列インスタンスとは異なりますが、配列の内容は同じ。そして、新しい配列の配列要素の内容を一部変えても、その影響はコピー元の配列には影響しません。
従って、配列要素がString型の場合のarraycopy()メソッドもディープコピーで新しい配列を作ります

>&gt;java StrArrayCopy
arrayOrg:[Ljava.lang.String;@15db9742 arrayNew:[Ljava.lang.String;@6d06d69c
arrayOrg != arrayNew
arrayOrg[] equals arrayNew[]

change arrayNew[1] = A
arrayOrg[0] = A   arrayNew[0] = A
arrayOrg[1] = B   arrayNew[1] = A
deep copy

>

最後に、配列要素がオブジェクト型の場合です。
5行目から8行目で作成する配列をObjArrayというオブジェクト型に変えて、同じ処理を行います。

import java.util.*;

public class ObjArrayCopy {
	public static void main(String[] args) {
		ObjArray[] arrayOrg = {
			new ObjArray(10),
			new ObjArray(20)
		};
		ObjArray[ ] arrayNew = new ObjArray[2];
		System.arraycopy(arrayOrg, 0, arrayNew, 0, arrayOrg.length);
		System.out.println("arrayOrg:" + arrayOrg + " arrayNew:" + arrayNew);
		if (arrayOrg == arrayNew) {
            System.out.println("arrayOrg == arrayNew");
        } else {
            System.out.println("arrayOrg != arrayNew");
        }

        if (Arrays.equals(arrayOrg, arrayNew)) {
            System.out.println("arrayOrg[] equals arrayNew[]");
        } else {
            System.out.println("arrayOrg[] not equals arrayNew[]");
        }

        arrayNew[1].num = 10;
		System.out.println("\nchange arrayNew[1].num = 10");
        for (int i = 0; i < arrayOrg.length; i++) {
            System.out.println("arrayOrg[" + i + "] = " + arrayOrg[i] + "   "
            				+ "arrayNew[" + i + "] = " + arrayNew[i]);
        }
		if(arrayNew[1].equals(arrayOrg[1])) System.out.println("shallow copy");
		else System.out.println("deep copy");
	}
}

class ObjArray {
	int num;
	ObjArray(int num) {
		this.num = num;
	}
}

この場合も、新しい配列が指し示す配列インスタンスはコピー元の配列インスタンスとは異なりますが、配列の内容は同じ。しかし、新しい配列の配列要素の内容を一部変えると、その影響はコピー元の配列には影響してしまいます。
つまり、配列要素がオブジェクト型の場合のarraycopy()メソッドは配列インスタンスをディープコピーで作成しますが、各配列要素が指し示すオブジェクトはシャロ―コピーで作成します

>java ObjArrayCopy
arrayOrg:[LObjArray;@15db9742 arrayNew:[LObjArray;@6d06d69c
arrayOrg != arrayNew
arrayOrg[] equals arrayNew[]

change arrayNew[1].num = 10
arrayOrg[0] = ObjArray@7852e922   arrayNew[0] = ObjArray@7852e922
arrayOrg[1] = ObjArray@4e25154f   arrayNew[1] = ObjArray@4e25154f
shallow copy

>

この様に、同じarraycopy()メソッドでもコピーする配列の内容によりコピーによって作られる配列の作りが変わるので、注意が必要です。

さて、以上の事からarraycopy()はclone()と同じ配列のコピーが出来る事が分かりましたが、何か違いはないのでしょうか。

それはarraycopy()がコピーの開始位置やコピーする配列要素数を指定できるだけでなく、ソース配列srcと転送先の配列destに同じ配列オブジェクトを指定できる事がarraycopy()の特徴です。

import java.util.*;

public class ObjArrayCopyInner {
	public static void main(String[] args) {
		ObjArray[] arrayOrg = {
			new ObjArray(10),
			new ObjArray(20),
			new ObjArray(30)
		};
		System.out.println("arrayOrg before arraycopy:" + arrayOrg);
		for (int i = 0; i < arrayOrg.length; i++) {
            System.out.println("arrayOrg[" + i + "] = " + arrayOrg[i].num);
        }
		
		System.arraycopy(arrayOrg, 0, arrayOrg, 1, 2);
		
		System.out.println("arrayOrg after arraycopy:" + arrayOrg);
		for (int i = 0; i < arrayOrg.length; i++) {
            System.out.println("arrayOrg[" + i + "] = " + arrayOrg[i].num);
        }
	}
}

class ObjArray {
	int num;
	ObjArray(int num) {
		this.num = num;
	}
}
>java ObjArrayCopyInner
arrayOrg before arraycopy:[LObjArray;@15db9742
arrayOrg[0] = 10
arrayOrg[1] = 20
arrayOrg[2] = 30
arrayOrg after arraycopy:[LObjArray;@15db9742
arrayOrg[0] = 10
arrayOrg[1] = 10
arrayOrg[2] = 20

>
カテゴリー: Java | タグ: , , | 配列のコピー arraycopy() はコメントを受け付けていません

配列のコピー clone()

配列のコピーは日常的に行われる処理です。
通常、forループで要素をコピーしたり、clone()メソッドを使ったりします。さらに、arraycopy()を利用することも出来ます。
しかし、見た目が「コピー」であっても、コピーの実現方式にはシャローコピーとディープコピーの二種類あるので、それぞれどう実現されているかを知っておくと良いでしょう。

シャローコピー(shallow copy:奥行きの無いコピー)

配列の参照情報をコピーします。コピーで作成した配列変数はコピー元の配列インスタンスを指し示しているので、コピー元の要素を変更しても、新しい配列の要素を変更しても、変更は両方に行われたと見えます。

ディープコピー(deep copy:突き詰めたコピー)

元の配列の内容を含めてコピーし新しい配列を作ります。コピーで作成した配列変数はコピー元の配列インスタンスではなく新しい配列インスタンスを指し示し、新しい配列インスタンスの中身はコピー元の配列の中身と同じものになっています。コピー元の要素を変更しても、新しい配列の要素を変更しても、変更が相手方に反映することはありません

新しく作った配列にforループで内容をコピーすれば、結果は当然ディープコピーになります。
一方、clone()メソッドで新しい配列を作成すると一般的にはシャローコピーになると考えられています。しかし、clone()メソッドはコピーする配列の内容によってシャロ―コピーにも、ディープコピーにもなるので注意が必要です。

配列要素が基本型の場合
int型の配列arrayOrg[]を作り、そのclone()メソッドでarrayNew[]を作ります。
まず、9行目で二つの配列変数の内容を比較し、配列変数が同じ配列インスタンスを指しているか否かを確認しています。
次にそれぞれの配列インスタンスの中身が同一化を確認。
その上で、19行目で新しい配列の要素の内容を変更し、その変更がコピー元の配列に影響するか確認し、影響していればシャローコピー、指定なければディープコピーとしています。

import java.util.*;

public class IntArrayClone {
	public static void main(String[] args) {
		
		int[] arrayOrg = { 10, 20 };
		int[] arrayNew = arrayOrg.clone();
		System.out.println("arrayOrg:" + arrayOrg + " arrayNew:" + arrayNew);
		if (arrayOrg == arrayNew) {
            System.out.println("arrayOrg == arrayNew");
        } else {
            System.out.println("arrayOrg != arrayNew");
        }
        if (Arrays.equals(arrayOrg, arrayNew)) {
            System.out.println("arrayOrg[] equals arrayNew[]");
        } else {
            System.out.println("arrayOrg[] not equals arrayNew[]");
        }
        arrayNew[1] = 10;
		System.out.println("\nchange arrayNew[1] = 10");
        for (int i = 0; i < arrayOrg.length; i++) {
            System.out.println("arrayOrg[" + i + "] = " + arrayOrg[i] + "   "
            				+ "arrayNew[" + i + "] = " + arrayNew[i]);
        }
		if(arrayNew[1] == arrayOrg[1]) System.out.println("shallow copy");
		else System.out.println("deep copy");
	}
}

実行結果は、新しい配列が指し示す配列インスタンスはコピー元の配列インスタンスとは異なりますが、配列の内容は同じ。そして、新しい配列の配列要素の内容を一部変えても、その影響はコピー元の配列には影響しない事を示しています。
従って、配列要素が基本型の場合のclone()メソッドはディープコピーで新しい配列を作ります

>java IntArrayClone
arrayOrg:[I@15db9742 arrayNew:[I@6d06d69c
arrayOrg != arrayNew
arrayOrg[] equals arrayNew[]

change arrayNew[1] = 10
arrayOrg[0] = 10   arrayNew[0] = 10
arrayOrg[1] = 20   arrayNew[1] = 10
deep copy

>

次に、配列要素がString型の場合
6行目で作成する配列をString型に変えて、同じ処理を行います。

import java.util.*;

public class StrArrayClone {
	public static void main(String[] args) {
		
		String[] arrayOrg = { "A", "B" };
		String[] arrayNew = arrayOrg.clone();
		System.out.println("arrayOrg:" + arrayOrg + " arrayNew:" + arrayNew);
		if (arrayOrg == arrayNew) {
            System.out.println("arrayOrg == arrayNew");
        } else {
            System.out.println("arrayOrg != arrayNew");
        }
        if (Arrays.equals(arrayOrg, arrayNew)) {
            System.out.println("arrayOrg[] equals arrayNew[]");
        } else {
            System.out.println("arrayOrg[] not equals arrayNew[]");
        }
        arrayNew[1] = "A";
		System.out.println("\nchange arrayNew[1] = A");
        for (int i = 0; i < arrayOrg.length; i++) {
            System.out.println("arrayOrg[" + i + "] = " + arrayOrg[i] + "   "
            				+ "arrayNew[" + i + "] = " + arrayNew[i]);
        }
		if(arrayNew[1].equals(arrayOrg[1])) System.out.println("shallow copy");
		else System.out.println("deep copy");
	}
}

結果は同じく、新しい配列が指し示す配列インスタンスはコピー元の配列インスタンスとは異なりますが、配列の内容は同じ。そして、新しい配列の配列要素の内容を一部変えても、その影響はコピー元の配列には影響しません。
従って、配列要素がString型の場合のclone()メソッドもディープコピーで新しい配列を作ります

>java StrArrayClone
arrayOrg:[Ljava.lang.String;@15db9742 arrayNew:[Ljava.lang.String;@6d06d69c
arrayOrg != arrayNew
arrayOrg[] equals arrayNew[]

change arrayNew[1] = A
arrayOrg[0] = A   arrayNew[0] = A
arrayOrg[1] = B   arrayNew[1] = A
deep copy

>

最後に、配列要素がオブジェクト型の場合です。
5行目から8行目で作成する配列をObjArrayというオブジェクト型に変えて、同じ処理を行います。

import java.util.*;

public class ObjArrayClone {
	public static void main(String[] args) {
		ObjArray[] arrayOrg = {
			new ObjArray(10),
			new ObjArray(20)
		};
		ObjArray[ ] arrayNew = arrayOrg.clone();
		System.out.println("arrayOrg:" + arrayOrg + " arrayNew:" + arrayNew);
		if (arrayOrg == arrayNew) {
            System.out.println("arrayOrg == arrayNew");
        } else {
            System.out.println("arrayOrg != arrayNew");
        }

        if (Arrays.equals(arrayOrg, arrayNew)) {
            System.out.println("arrayOrg[] equals arrayNew[]");
        } else {
            System.out.println("arrayOrg[] not equals arrayNew[]");
        }

        arrayNew[1].num = 10;
		System.out.println("\nchange arrayNew[1].num = 10");
        for (int i = 0; i < arrayOrg.length; i++) {
            System.out.println("arrayOrg[" + i + "] = " + arrayOrg[i] + "   "
            				+ "arrayNew[" + i + "] = " + arrayNew[i]);
        }
		if(arrayNew[1].equals(arrayOrg[1])) System.out.println("shallow copy");
		else System.out.println("deep copy");
	}
}

class ObjArray {
	int num;
	ObjArray(int num) {
		this.num = num;
	}
}

この場合も、新しい配列が指し示す配列インスタンスはコピー元の配列インスタンスとは異なりますが、配列の内容は同じ。しかし、新しい配列の配列要素の内容を一部変えると、その影響はコピー元の配列には影響してしまいます。
つまり、配列要素がオブジェクト型の場合のclone()メソッドは配列インスタンスをディープコピーで作成しますが、各配列要素が指し示すオブジェクトはシャロ―コピーで作成します

>java ObjArrayClone
arrayOrg:[LObjArray;@15db9742 arrayNew:[LObjArray;@6d06d69c
arrayOrg != arrayNew
arrayOrg[] equals arrayNew[]

change arrayNew[1].num = 10
arrayOrg[0] = ObjArray@7852e922   arrayNew[0] = ObjArray@7852e922
arrayOrg[1] = ObjArray@4e25154f   arrayNew[1] = ObjArray@4e25154f
shallow copy

>

この様に、同じclone()メソッドでもコピーする配列の内容によりコピーによって作られる配列の作りが変わるので、注意が必要です。

カテゴリー: Java | タグ: , , , , | 配列のコピー clone() はコメントを受け付けていません

final修飾子

「変数宣言初期化時にfinal修飾子を付けると定数宣言になる。」という事は知られていますが、final修飾子は変数以外にもクラス、メソッドにも付けることが出来ます。

クラスに付けた場合

そのクラスは継承不可になり、継承を宣言した側でコンパイルエラーが発生します。

メソッドに付けた場合

そのメソッドはオーバーライド不可になり、サブクラス側のオーバーライド宣言時にコンパイルエラーになります。

クラスはメソッドをfinal修飾するのはクラスやメソッドを変更されないようにする場合か、十分に継承が考慮できていないために変更を禁止する場合であって、プログラミングの自由度を損なうクラス、メソッドへのfinal修飾は安易に行うべきではありません

一方、変数にfinal修飾子を付けることは良く行われますが、いろいろなケースがあるので、それぞれ注意が要ります。

クラス変数をfinal修飾

final修飾子はメソッド内のローカル変数に指定することはもちろんですが、定数を様々なクラスで使用する場合には、一か所で定義した方が効率的であり、修正時の誤りも避けられます。そのためにはfinalに合わせてstaticをフィールドに対して修飾します。順番は順不同で構いません。

インスタンス変数をfinal修飾

インスタンス変数の参照情報は変更不可なので、一度作成したインスタンス変数に対し新たなインスタンスを代入しようとするとコンパイルエラー。しかし、既存のインスタンスのフィールド値を変更するのは可能です。

メソッド引数にfinal修飾

引数を受取った側で、引数に値を代入することが出来ません。ただし、受け取った引数がオブジェクトであればオブジェクトのフィールド値を変更することは可能です。
カテゴリー: Java | タグ: , , , , , | final修飾子 はコメントを受け付けていません

構造化例外処理

プログラミングの中でエラー処理は重要です。
プログラムは行いたいことを実現するための物ですが、何かを実現する作業の中には必ず外乱が発生します。それらの外乱を事前に想定して、外乱が発生した場合の対処がエラー処理です。だからと言って処理手順ごとにプログラマーが思い思いにエラー処理を行っていたら、プログラムが何を行いたいのか、処理の流れが分かりにくくなってしまいます。

そこでJavaではプログラムの可読性を高めるため、行いたい処理とエラー処理を分離し、行いたい処理の中に意味合いの違うエラー処理が混在しないように、二つを構造化して分離するプログラミング手法「構造化例外処理」が推奨されます。
ここで、「エラー処理」と「例外処理」の意味が違うように感じますが、Javaでは広義のエラーを狭義のエラーと例外に分け、プログラムによる対処が可能な例外について処理機構を作り、その処理機構が狭義のエラーも扱えるようにしているため、広義のエラー全体を扱える処理を例外処理と呼んでいます。
狭義のエラーや例外の詳細については例外処理を参照ください。

「構造化例外処理」の構文はtry-catch-finallyの三つのブロックで構成され、tryブロックに行いたい処理、catchブロックに処理によって発生する可能性のある例外の回復処理、そしてfinallyブロックに例外発生の有無にかかわらず実行したい処理を記述します。
さらに例外が発生した場合、その発生したメソッド内でキャッチして例外を処理することも、メソッド名に続けてthrows宣言を行い、例外処理をメソッドの呼び出しもとに移譲することも出来ます。なお、例外処理の移譲によってメソッド呼び出しの大元で例外を一元管理して処理することが出来ます。

try ブロック内には、複数の文を記述できます。もし例外が発生したらtry ブロック内の以降の処理はスキップされ、すぐに対応するcatch ブロックに制御が移ります
catch ブロックの目的はプログラムを正常な状態に復帰させることで、キャッチできる例外はすべての例外のルートクラスであるThrowableクラス、例外処理が必須のExceptionクラスだけでなく、例外処理が必須ではないErrorクラスやRuntimeExceptionクラスもキャッチできます。catchブロックの処理が終了すると「不具合は対処された」として、finallyブロックの処理に移ります。なお、throws宣言して例外をメソッドの呼び出し元に移譲する場合にはcatchブロックは省略できます。
finallyブロックは必ず実行されるブロックであり、例外をthrows宣言している場合、例外が移譲される前に実行されます。またcatchブロックにreturn文がある場合でも、return処理の前にfinallyブロックが実行され、その後catchブロックのreturnが実行されます。
try-catch-finallyの構文は、各ブロックの順序を変更することはできません。誤った順序で記述するとコンパイルエラーになります。tryブロックとfinallyブロックは1つずつしか記述できず、複数記述するとコンパイルエラーになります。一方、catchブロックは複数記述できます。
なお、catchブロックを複数記述する場合はcatchする例外の順序はサブクラスを先頭にする必要があります。これは例外クラスのインスタンスも、ほかのクラスと同様にポリモーフィズムが成り立ち、サブクラスの例外クラスのcatchはスーパークラスの例外処理がcatch可能であり、結果サブクラスの例外処理がスーパークラスの例外処理の後に記述されていると、サブクラスの例外処理は常に実行されない事になるからです。このような場合、コンパイラーは到達不可能なコードをあるとして、コンパイルエラーを発生します。

複数のtry-catchがネストしている場合、スローされた例外を受け取るのは、その例外に対応したもっとも近いcatch ブロックです。ネスト階層ごとにfinallyブロックがある場合は、ネストの内側から順にすべてのfinallyブロックが実行されます。

カテゴリー: Java | タグ: , , , , | 構造化例外処理 はコメントを受け付けていません

例外処理

Javaでは、プログラム実行中に発生するエラーや例外に対し適切な対応が取れるよう、try – catch – finallyブロックによる構造化例外処理が行えます。
例外処理の中では事前に定義された例外クラスを使って発生した例外を検出し、例外ごとに対応した対処を記述します
勿論、発生し得る例外全てに例外クラスが定義されているわけではないので、プログラムの処理に合わせ既存の例外クラスを継承して独自の例外クラスを定義することが可能です。

Javaにおける例外は、大きく2つに分かれます。

エラー(Error)
実行環境のトラブルなど、プログラムからは回復不可能なトラブルが発生したことを指します。
トラブルが発生した場合、JVMがErrorクラスまたは、そのサブクラスのインスタンスを生成しプログラムに適知します。
ただ、通知されたエラーはプログラムで対処できない事象なのでtry-catch したり、throws宣言する必要はありません。勿論、例外処理を記述することは可能で、検出されたエラーをユーザに知らせ対応をユーザに委ねることはできます。
例外(Exception)
プログラムが対処できる不具合(例外)です。
例外はさらに、検査例外と非検査例外に分かれます。
検査例外
例外処理を記述して正常な処理に復帰させることが可能な例外であり、プログラムで対処することが必須です。従って、コンパイラは例外処理の記述があるかどうかを確認し、必要な例外処理が存在しない場合はコンパイルエラーを出します。
対象はException及び、RuntimeExceptionを除くExceptionのサブクラスで、対処は検査例外が発生する可能性のある処理を、try-catchするか、throws宣言をしてメソッド呼び出し元に例外処理を移譲します。
非検査例外
プログラムでは対処が完全には行えないRuntimeExceptionとそのサブクラスの例外です。従って、try-catchなどの対処は必要なく、コンパイラは例外処理の記述あるかどうかを検査しません。
例外処理は必須ではありませんが、勿論try-catchして例外を検出し可能な範囲の対処を行い、正常終了させることは可能です。
全ての例外はThrowableクラスのサブクラスであり、各クラスの継承関係は、
Object
 ┃
Throwable
 ┣━Error
 ┗━Exception
    ┗━RuntimeException
となっています。

各例外の概要は以下の通りです。
Error
プログラム処理では回復出来ない不具合のため例外処理の記述は不要です。プログラム実行前にこのようなエラーが発生しないように実行環境を整えておく必要があります。
NoClassDefFoundError
JVMが実行対象のクラスファイルを発見できなかった
コンパイル時点で存在していたクラスが、見つからない
StackOverflowError
JVMが「再帰呼び出し」などで、スタック領域の不足を検出し、プログラムを強制終了
OutOfMemoryError
JVMがインスタンスを保存したり、クラスの定義情報を保存したりするヒープ領域が一杯になり、新しいオブジェクトを割り当てることができない
ExceptionInInitializerError
JVMがstaticイニシャライザを処理している間に例外が発生(NullPointerExceptionなど)したとき、例外の通達相手がいないのでErrorを発生させ、プログラムを強制終了
Exception
プログラム処理による回復が可能な不具合のため例外処理の記述が必須です。コンパイラーは例外処理の記述をチャックします。
ClassNotFoundException
クラスの文字列名を使用してforName、findSystemClass、loadClassメソッドでロードしようとしたが、指定された名前のクラスの定義が見つからなかった
IOException
入出力処理の失敗、または割り込みの発生による例外
FileNotFoundException
指定されたパス名で示されるファイルが開けなかった
SQLException
データベース操作時に発生した例外
RuntimeException
プログラム処理による完全な回復は不可能であり、例外処理の記述ではなく開発段階でロジックを精査し不具合が発生しないようにする必要があります。なお、コンパイラーは例外処理の記述をチャックしません。
ArithmeticException
ゼロ割等、不能演算が指示された
IllegalArgumentException
利用される側のオブジェクトが不正な引数を受取った
NumberFormatException
parselntメソッドが変換形式に合わない引数を受取った
例えば、Integerクラスのparselntメソッドに文字として英数字以外を渡す。
IndexOutOfBoundsException
配列や文字列、コレクションの範囲外アクセス
ArrayIndexOutOfBoundsException
配列の範囲外アクセス
public class Main01 {
	public static void main(String[] args) {
		String[] str = new String[1];
		for(String s :str) {
			System.out.println(s + " , " + str[1]);
		}
	}
}
>java Main01
Exception in thread &quot;main&quot; java.lang.ArrayIndexOutOfBoundsException: 1
        at Main01.main(Main01.java:5)

>
StringlndexOutOfBoundsException
文字列の範囲外アクセス
public class Main03 {
	public static void main(String[] args) {
		String str = "string";
		System.out.println(str.charAt(6));
	}
}
>java Main03
Exception in thread &quot;main&quot; java.lang.StringIndexOutOfBoundsException: String index out of range: 6
        at java.lang.String.charAt(Unknown Source)
        at Main03.main(Main03.java:4)

>
NullPointerException
オブジェクト参照がnullの状態で、インスタンスにアクセス
配列変数がnullなのに、配列のサイズを調べる
public class Main02 {
	public static void main(String[] args) {
		String[][] str = null;
		System.out.println(str.length);
	}
}
>java Main02
Exception in thread &quot;main&quot; java.lang.NullPointerException
        at Main02.main(Main02.java:4)

>
ClassCastException
継承関係や実現関係にない型に互換性のないクラスをキャストしようとした。
(コンパイル時には検出できず実行時に例外発生)
IlegalStateException
利用される側のオブジェクトが、まだ利用するための準備が終わっていない
カテゴリー: Java | タグ: , , , , , | 例外処理 はコメントを受け付けていません

UML クラス間相互関係

UML(Unified Modeling Language)におけるクラス間の「相互関係」の種類及び関係の表現法をまとめます。また、Javaのクラス実装との対応も付記します。

関連(association)

クラス間に何らかの結びつきがある関係
「has-a関係」AはBを持っている関係
[実装]データメンバが他のクラスのインスタンスを参照する。

集約(aggregation)

クラス間に関連よりも強い結びつきがある関係
「owns-a関係」AはBを所有している関係
二つのクラスが「全体-部分」の関係だが、他のクラスとの共有の場合もありうる。
なお、ひし形は相手を所有する、「全体」側に付きます。
[実装]データメンバが他のクラスのインスタンスを参照する。

コンポジション(composition)

クラス間に集約よりも強い結びつきがある関係
「part-of関係」BはAの一部である完全な包含関係
二つのクラスが「全体-部分」の独占関係で同時に生成・消滅する。
なお、ひし形は相手を所有する、「全体」側に付きます。
[実装]データメンバが他のクラスのインスタンスを参照する。

依存(dependency)

あるクラスが別のクラスを一時的に利用する関係
[実装]あるクラスのメソッド内で別のクラスのインスタンスを使用する。

汎化(generalization)

あるクラス(スーパークラス)を元に別のクラス(サブクラス)を派生させ、元のクラスの属性・操作も引き継ぐ関係
「is-a関係」Bはある種のAである関係
Javaでいう「継承」
なお、サブクラスからスーパークラスを導くのが汎化、逆にスーパークラスからサブクラスを導くのが特化

実現(realization)

他のクラスに「扱い方」、具象化時の条件を規定する関係
Javaでいう「Interface」
カテゴリー: Java | タグ: , , , , , , , , , , , , , | UML クラス間相互関係 はコメントを受け付けていません

アクセス修飾子 その他

1 アクセス修飾子はパケージ指定と組む合わせてアクセス制御機能を提供します
パッケージ単位でアクセス制御可能
2 メソッドのオーバーライドではアクセス修飾子は同じレベルか、より制限の緩いものでなければいけません
3 アクセス修飾子が異なってもオーバーロードではありません
アクセス修飾子はシグネチャの対象外です。
4 コンストラクタには全てのアクセス修飾子が指定可能です
publicは、どのクラスからでも対象のクラスをインスタンス化できることを表します。
protectedや指定なし(デフォルト)は継承関係にあるサブクラスやパッケージ内のクラスだけが対象のクラスをインスタンス化できるように制限をかけます。
privateは非公開のコンストラクタを定義するために使います
非公開のコンストラクタの用途は、あるアプリケーション内でインスタンスが1つしかないことを保証したり、コンストラクタをオーバーロードして複数定義し、公開するコンストラクタと非公開にするコンストラクタに分ける(公開コンストラクタの中で非公開コンストラクタを呼ぶ)ためにも使います。
5 インタフェースはコンパイラによって自動的にpublicで修飾されます
インタフェースはほかのクラスからの「扱い方」を規定したものであり、ほかのクラスから扱えるようにしておく必要があります。規定なお、インタフェースに定義するメソッドは、protected やprivate で修飾することはできません。
カテゴリー: Java | タグ: , | コメントする