パッケージと例外処理あたりにめちゃくちゃわかりにくい部分をまとめてみた
今日はパッケージとか例外処理らへんです。
パッケージ
簡単に言えば、ディレクトリです。クラスをディレクトリに分けて記述します。
package A; public class Car{ //Carクラス }
package B; public class Sample { public static void main(String[] args){ //Sampleクラス } }
このように記述できます。package A;とpackage B;が、それぞれ、パッケージAとパッケージBに属する、という意味です。この状態で、パッケージAのCarクラスをBで利用するには、クラス名の前にパッケージ名を指定します。つまり
B.Car car = new B.Car();
と記述します。また、import文を使った別の使い方もできます。この場合は以下のように記述します。
package A; public class Car{ //Carクラス }
package B; import A.Car; public class Sample { public static void main(String[] args){ //Sampleクラス } }
このようになります。記述方法はimport パッケージ名.クラス名;で記述します。さらにBでCarクラスを扱う場合は、importしてるので、いちいち変数名の前にパッケージ名を指定する必要はありません。
Car car = new Car();
となります。
また、パッケージを指定しないと「名前なしのパッケージ」に含められています。「名前なしのパッケージ」に含まれるものは、パッケージの概念について特に意識する必要はない。
パッケージの注意点
- 同じソースファイル上のクラスを、異なるパッケージにわけることはできない。
- 異なるパッケージからクラスを利用できるようにするためには、publicを修飾子として指定する。なお、publicをつけたクラスは1つのソースファイル上に1つだけしか記述できない。そして、ファイル名はpublicを付けたクラス名と同じにする。
- パッケージ名が異なれば、同じクラス名でも全く別のものとして扱われる。
- パッケージの下にさらにサブパッケージを作って、パッケージ内でも階層構造を作ることができる。
package A; public class Sample1 { }
package B; import A; public class Sample2 extends Sample1 { }
package C; import A, B; class Sample3 { //mainメソッド }
Aと、AをimportしたBとの両方をパッケージCにimportして扱うこともできる。
クラスライブラリのインポート
java.lang
基本的なクラス
java.io
入出力関連のクラス
java.util
ユーティリティ関連のクラス
ただしjava.langパッケージだけはインポートしなくてもクラス名の記述のみで扱えます。
例外処理
コードをコンパイルするときには見つけることはできないが、実行時にエラーがあることがわかる。この実行時エラーに対処するために例外処理という仕組みがある。
try { 例外の発生を調べる文 } catch ( 例外のクラス 変数名 ) { 例外が起きたときの処理 }
tryブロック内で例外が起きると処理中断
↓
catchブロックの例外の種類と一致すれば、ブロック内の処理を行う
↓
try-catchブロックの後から処理が続けられる。
catchブロックの中で適切に処理を行う。処理がなかったら、エラーをもみ消すことになる。もしも例外に対するcatchブロックが見つからなかったら、呼び出し元のメソッドに戻ってさらにcatchブロックを探す。最終的にmainメソッド上にcatchできるものがなかった場合、実行時エラーとして出力される。(処理が中断されたまま終了する。)
finallyブロック
例外が起きる起きないに関わらず、必ず最後に実行される。finallyブロックに重要な処理を記述しておくことで、例外が発生した際に、その処理が飛ばされたまま次のプログラムの処理が進んでしまう危険性を排除できる。
try { 例外の発生を調べる文 } catch ( 例外のクラス 変数名 ) { 例外が起きたときの処理 } finally { 必ず最後に処理をする }
実際には、プログラムの後始末の処理に使われることが多い。
A { try { Bメソッドの呼び出し } catch { //エラーに対する例外処理 } finally { //必ず行われる処理 } } B { try { //エラーが起こるメソッド } catch { //エラーに対する例外処理 } finally { //必ず行われる処理 } }
通常時
①まずAのtry文の中で、Bメソッドが呼ばれます
②Bのtry文の中のメソッドで、実行時エラーが起きる
③Bのcatch文で例外処理が行われるかどうか判断する
④Bのcatch文で例外処理が行われると、Bのfinally文が実行される
⑤Aの呼び出し元のメソッドに戻る
⑥(Aの中で他にエラーがなければ)Aのfinallyが行われる
Bのcatch文で例外処理ができなかった場合
①まずAのtry文の中で、Bメソッドが呼ばれます
②Bのtry文の中のメソッドで、実行時エラーが起きる
③Bのcatch文で例外処理が行われるかどうか判断する
④Bのcatch文で例外処理が行われなかった場合、Bのfinally文が実行されてからAのcatch文に戻る
⑤Aのcatch文で例外処理が行われる
⑥(Aの中で他にエラーがなければ)Aのfinallyが行われる
基本的には、まずは自分のメソッド内で処理を完結しようとするが、対応するcatchがなかった場合のみ、finallyを実行した上で、メソッドを跨ぐことになる。
例外クラス
ArrayIndexOutOfBoundsExceptionとは、Throwableクラスのサブクラスから拡張された、ArrayIndexoutOfBoundsExceptionというクラスのオブジェクト、と言えるそうです。ThrowableクラスからはErrorクラスとExceptionクラスの2つが拡張されている。Errorクラスはプログラムの実行が続行できないようなエラーなので例外処理は行いません。
ExceptionクラスからはさらにRuntimeExceptionというクラスが拡張されています。ここからさらに拡張されているのが、ArrayIndexOutOfBoundsExceptionです。
例外の送出
自分で例外をつくることができる。その際にはThrowableクラスのサブクラスを拡張して独自の例外クラスをつくる。
戻り値の型 メソッド名(引数) throws 例外クラス
とすることで独自の例外を投げることができる。
例外が送出される可能性がある場合には
①try-catchを使って、そのメソッド内で例外を受け取って処理してしまう
②throwsを記述して、そのメソッドを利用する呼び出し元のメソッドに例外処理をまかせることを示す。
①は、エラーが生じたそのメソッド内にtry-catch文が存在して、その場で処理する。
②は、エラーが生じたメソッド内にtry-catch文はなく、その呼び出し元のメソッド内にtry-catch文があるか、または最後まで投げられて結局mainメソッドに戻り、実行時エラーとなるか。処理の場所を選ぶことができる。
入出力の基本
入出力機能を支える概念をストリームという。
文字の標準入力
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
これは標準入力を指定して、文字ストリームを作成し、バッファを介して読み込むという一文です。ちなみにSystem.outと書くと標準出力を示します。
InputStreamReaderクラス…文字ストリーム
BufferedReaderクラス…バッファを介して読み込むための文字ストリーム
ファイルへの出力
PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter("test1.txt")));
FileWriterクラス…ファイルに書き込むための文字ストリーム
BufferedWriterクラス…バッファを介して書き込むための文字ストリーム
PrintWriterクラス…1行書き出すための文字ストリーム
println()メソッドを使って1行データを書き出す。
ファイルからの入力
BufferedReader br = new BufferedReader(new FileReader("test1.txt"));
FileReaderクラス…ファイルを読み込むための文字ストリーム
BufferedReaderクラス…バッファを介して読み込むための文字ストリーム
最後に
今日、例外クラスについて勉強してるときにNullPointerExceptionが出てきました。
僕は思わず、「ぬるぽ」と言いました。
おわり。
今日はここまで。
誤った表記等ございましたら、コメントを
頂けましたら幸いです。