ウィンドウアプリケーション CUI/GUI
☆ ウィンドウアプリケーションを作る
プログラムの見た目・操作性のこと・・・"ユーザーインタフェース"
〈文字ベースのインタフェース・・・CUI〉
ex. メインメニュー
1 会員登録
2 会員検索
〈デザインベースのインタフェース・・・GUI〉
ex. 「窓枠があってクリックするボタンがある画面」
→GUI開発に用いるボタンや入力ボックスなど、
様々な部品がクラスとして提供されている
import java.awt.FlowLayout;
import java.swing*;
public class Main{
public static void main(String[ ] args){
JFrame flame=new JFrame("はじめてのGUI");
JLabel label=new JLabel("Hello World!);
JButton=new JButton("押してね");
:
出力 「はじめてのGUI」と書いてあるフレームの中に
Hello World!と書いてあるラベルがあり、
押してねと書いてあるボタンがついている画面が出力される
データベース操作 java.sqlパッケージ
☆ データベースを操作する
データベースとは?
→データを整理して格納したソフトウェアとデータの集合体
(格納したデータを高速で取り出せる)
データベースに格納されている表の中の値を取得したり、書き換えるためには
「SQL」というデータベース専用の言語で
データベースに指示を送る必要がある(データベースにSQL文を送る)
public class Main{
public static void main(String[ ] args){
String dburl="jdbc: =true"; //接続先のデータベースを指定
String sql='INSERT INTO …('idea');
//ideaという名前の者を追加しろというSQL文の命令
Connection conn=DriverManager.getConnection(dburl);
//データベースに接続
conn.createStatement( ) executeUpdate(sql);
//SQLをデータベースに送信
conn.close( );
//データベースの接続を閉じる
}
}
インターネットへのアクセス java.netパッケージ
☆ インターネットへのアクセス
→インターネット上Webページの内容を取得する(java.netパッケージを使用)
ex. import java.io.InputStream;
import java.net.URL; //java.netパッケージ
public class Main{
public static void main(String[ ] args){
URL u=new URL("http://www….jp");
InputStream is=u.openStream( );
//openStream( )メソッドを呼び出すことでネットに接続する
//openStream( )メソッド
→このメソッドを呼ぶとインターネット上のページを上流に持つストリームが取得できる (Webサーバから1文字ずつ文字を読み込みながら、画面に出力していく)
int i=is.read( ); //最初の1文字を読み込む
while(i!=-1){//結果が-1で文字の読み込み終了なので
//(以下-1ではない場合の条件)
char c=(char)i;
System.out.print; //読んだ内容を画面に表示
i=is.read( ); //次の1文字を読み込む
}
}
}
出力内容 Webページを構成しているHTMLのテキストが画面に表示される
ちなみに、、、
〈出力〉 下流が画面に繋がっている小川(ストリーム) System.out
〈入力〉 上流がキーボードに繋がっている小川(ストリーム) System.in
ファイルの読み書き FileReader/FileWriter
☆プログラムからコンピュータの中にあるファイルを読み書きする場合
一度に一気に読み込んでいるわけではなく、ファイルを少しずつ読み込んでいる
(一度に読み込むとメモリが足りなくなるから)
コンピュータからプログラムへ読み込んでいる最中に文字が通っている道
…"ストリーム"
・ ファイルから文字を読み込む場合(1文字ずつファイルを読み込む)
→"java.io.FileReader"というAPIを利用する
ex. import java.io*;
public class Main{
public static void main(String[ ] args){
String filename="c:¥text.txt"; //ファイル名をセット
FileReader fr=new FileReader(filename); //ファイルを開く
char c1=(char)fr.read( ); //最初の1文字を読み込む
char c2=(char)fr.read( ); //次の1文字を読み込む
finally fr.close( ); //ファイルを閉じる
}
}
FileReaderとは、「指定されたファイルが源流にある小川」のようなもの
read( );メソッドを呼ぶ度に1文字ずつ文字を取り出せる
read( );の結果が-1の場合、
ファイルを最後まで読み終わったことを意味する
読み終わったら、ファイルが開けっ放しにならないように必ずファイルを閉じる
(どんな時でも処理が実行されるfinallyを最初につけること)
・ ファイルへ文字や文字列を書き込む場合
→"java.io.FileWriter"というAPIを利用する
ex. import java.io*:
public class Main{
public static void main(String[ ]args){
String filename="c:¥¥text.txt"; //ファイル名をセット
FileWriter fw=new FileWriter(filename); //ファイルを開く
fw.write('そ'); //最初の1文字を書き込む
fw.write('れ'); //最初の2文字
finally fw.close( ); //ファイルを閉じる
}
}
FileWriterとは、「指定されたファイルが下流に繋がっている小川」のようなもの
スロリームに流した文字がファイルに書き込まれている
※「Bufferred Writer」クラスを使用することも多い
例外状況の報告 〜thowで例外を投げる〜
☆ 例外的状況をJVMに報告する
例外状況を監視しているJVMに対して私たちが「~Exceptionという例外状況になりました」と報告することができる
→これにより、自分が作成したクラスに例外状況が発生した際に、きちんと例外処理が発生するかを事前にチェックすることができる
〈構文 例外状況の報告~例外を投げる〉
throw 例外インスタンス:
(例外インスタンスには、例外の詳細情報が詰め込んである)
JVMに今すぐ代替案実施(catch文を実行してシステムから抜けるなど)をしろという指示
→「例外を投げる」
※ 一般的には「throw new 例外クラス名("エラーメッセージ");」
ex. public class Person{
int age;
public void setAge(int age){
if(age<0){
throw new IllegalArgumentException("年齢は正の数を指定すべきです。指定値="+age);
} //もし年齢に負の値がセットされたらMainに投げつける
}
this.age=age; //問題ないならフィールドに値をセット
}
public class Main{
public static void main(String[ ] args){
Person p=new Person( );
p.setAge(-128); //テストとして誤った値のセットを試みる
}
※ try-catch文が不要になるスロー宣言で使うthrowsと
例外状況の報告で使うthrowは似ているけど、全く違うものなので注意
・既存の例外クラスに例外状況に対応するクラスがない場合
→既存の例外クラスを継承してオリジナルの例外クラスを作る
ex.音楽プレイヤーソフト
「対応していない形式のファイルを作成しようとした」という場面に対応できる例外クラスを使いたいが、既存のクラスにはない
→ RuntimeExceptionを継承して、オリジナルの例外クラスを作成する
〈継承元となりうるクラスの種類〉
IOException Exception RuntimeException など
ただ上記の継承元の親クラス
ThrowableやErrorの子クラスとしてオリジナルを定義することはほとんどない
(上記のクラスの子クラスとしてIOExceptionなどが既に定義されているから)
ex. オリジナル例外を定義
public class UnsupportMusicFileException extends Exception(String msg){
//対応されていない形式のファイルを作成しようとした場合 //Exception(チェック例外)を継承
//エラーメッセージを受け取るコンストラクタ
public Unsuport…Exception(String msg){
super(msg);
//継承元のクラスのコンストラクタへ情報(String msg)を渡す
}
}
オリジナル例外を利用
public class Main{
public static void main(String[ ] args){
try{
//試験的に例外を発生させる
throw new Unsupport……Exception("未対応のファイルです");
//("未対応のファイルです")→定義されているクラスの中の引数String msgが受け取る
}catch(Exception e){
e.print StackTrace( );
//JVMが行った例外処理の手順全表示
}
※ 大規模なプログラム開発では、
プログラムで想定されるさまざまな例外的状況を思い浮かべ、
オリジナルの例外クラスとして作成することで、
きめ細かい実行時エラーの対応が可能になる
例外の伝播 〜thows宣言〜
☆ 例外の伝播
↑
・sub( )メソッド内では、subsub( )メソッドを呼ぶ
↑
・subsub( )メソッド内では何らかの例外が発生する可能性がある
もし例外が発生する可能性のある箇所にtry-catch文の記述がなかった場合、
呼び出し元(main)まで処理を遡ってお手上げされる…..例外の伝播
:
これを利用して
逆に呼び出し側が一括で例外処理を行うこともできる
(毎回例外発生する可能性がある場所にtry-catch文を記述するのは面倒)
これを行えば、例外が発生する可能性のあるクラスは
わざわざtry-catch文で囲まなくても、thowsとだけ記述しておけばOK
〈構文〉
アクセス修飾子 戻り値 メソッド名(引数リスト) thows 例外が発生する可能性のあるクラス1、例外クラス2{
メソッド処理内容;
}
ex. public void subsub( ) thows IOException{
//IOExceptionが発生する可能性があるが、try-catch文はなくてもOK
FileWriter fw=new FileWriter( );
:
スロー宣言とは、
そのメソッドが「私はメソッド内で例外が発生しても処理はしませんが、私の呼び出し元が処理します」と表明する宣言
⇩
よって、スロー宣言が含まれるメソッドを呼び出す側は
「このメソッドを呼び出すと、呼び出し先で発生した例外が処理されずに自分に伝播してくる可能性がある」ことを覚悟しなければならない
:
呼び出し側はスロー宣言の書いてあるメソッドを呼び出すときに
"try-catch文で囲む義務が生まれる"
例外 try-catch-finally構文
☆ 例外
プログラムを設計する際は、実行時に想定外の事態が発生する可能性があることを考慮に入れておく必要がある
エラーを起こすことは絶対にダメ!
Javaのエラーは大きく分けると3種類
① 文法エラー(syntax error)
どこかの文法が間違っている
ex. セミコロンのつけ忘れ、変数名の間違い、クラス内部からしか呼び出せないprivateメソッドを外部から呼び出す
② 実行時エラー(runtime error)
プログラム実行中に突然動かなくなる
→実行中にエラーメッセージを表示して強制終了する
ex. 012と箱を用意した配列の3(用意している箱の範囲外)にアクセス
0で割り算、存在しないファイルを開く
③ 論理エラー(logic error)
実際に動かしてみると、プログラムの実行結果が想定していた内容と違う
エラーの原因 文法エラー
↓
気付く時 コンパイルするとエラーが発生して
失敗する
↓
対処 コンパイラが指摘したコードの箇所を修正する
エラーの原因 実行時エラー
↓
気付く時 実行すると途中で強制終了する
↓
対処 あらかじめ「エラーが発生した時の対応策」を記述しておく
エラーの原因 論理エラー
↓
気付く時 実行すると想定外の処理結果になる
↓
対処 原因箇所を自力で探してコード修正
②の実行時エラー
「プログラム実行中に想定外の事態が発生したこと」
想定外の事態…例外的状況/例外
ex. ・パソコンのメモリが足りなくなった
開発用はOKだったが、動作中に足りなくなった
・存在すべきファイルが見つからない
誤ってファイルを削除してしまったなど
・nullが入っている変数のメソッドを呼び出した
想定外操作で本来入るはずのない値(nullなど)が入った
⇨共通 プログラマが開発する時点では、想定外の事態(例外的状況)を予防できない
:
例外的状況に備えて対策を準備し、その状況に陥った際にその対策を実施する
→例外処理
〈例外的状況の対策をするための構文〉
try{本来の処理
}catch(IOException e){
//例外発生時に実行される文
System.out.println("エラー終了");
System.exit(1);
} ←例外を起こした際に、エラーが起こったということを知らせる表示の出力とその操作から脱出させるための処理
tryとcatchというブロックを使用(try-catch文)
通常実行されるのは、tryブロックの中の処理だけ。
catchブロックの中身は例外状況が発生した事を検知すると、
tryブロックの中で行われていた処理がcatchブロックの中に移行する
(そのため、catchブロックの中に「例外的な状況が発生したときに実行される処理」を記述しなければならない)
・例外の種類
1. Error
回復見込みがないから
catchしてもしょうがない
ex.OutOfMemoryError(メモリ不足)
classFormatError(クラスファイルが壊れている)
2.Exception
回復見込みがある状況
①Exception系例外
(java.lang.Exceptionの子孫の中からRuntimeExceptionの子孫を除いたもの)
その発生を十分に想定して対応を考える必要がある例外的状況を表すクラス
☆回復見込みがありので、catchすべき
ex.IOException(ファイルの読み書きができない)
ConnectException(ネットワークに接続できない)
②RuntimeException系例外
(java.lang.RuntimeExceptionのクラスの子孫)
必ずしも常に発生を想定すべきとまではいえない例外的状況
(いちいち処理してるとキリがない)
☆try-catch文を使うかは任意
ex.NullPointerException(変数がnull)
ArrayIndexOutOfBoundsException(配列の添字が不足)
この中で重要なのは①Exception系例外!
(なぜなら、対処すれば回復するから)
↓
JavaではException系例外が発生しそうな命令を呼び出す場合、
try-catch文を用いて「例外が発生した時の代替処理」を用意しておかないと
コンパイルエラーになる
ex. import java.io*: //FileWriterクラスが所属するパッケージ名
//FileWriterのコンストラクタはIOExceptionを発生する可能性がある
public class Main{
public static void main(String[ ] args){
try{FileWriter fw=new FileWriter("data.txt");
}catch(IOException e){
System.out.println("エラーが発生しました");
System.exit(1);
}
}
try-catch文を記述するためには、
「どのメソッドを呼び出したらどのような例外を発生させる可能性があるか」を
事前に知っておく必要がある
→APIリファレンスに掲載されているものを参考にする
ex.FileWriter
FileWriterのインスタンス生成時にコンストラクタを呼び出す時は
IOExceptionをキャッチする
↓
try-catch文が必要になるという解釈
public FileWriter(String fileName) throws IOException
//引数リストの後に「throws 例外クラス名」を表記
}catch(IOException e){
//例外状況の詳細が変数eに代入される
→この情報を取り出してエラーの状況を把握する
System.out.println("エラー:"+e.getMessage( ));
System.exit(1); //途中で処理から脱出
}
・String getMessage( )….例外的情報の解説文を表示する
・void print StackTrace( )…スタックトレースの内容を画面に出力する
スタックトレースとは?
「JVMがプログラムのメソッドをどのような状態で呼び出し、どこで例外が発生したか」という経緯が記録された情報
(実行時エラーが発生したときのエラー画面と内容は一緒)
☆ さまざまなcatch構文
(基本) try{
本来の処理
}catch(例外クラス 変数名e/ex){
例外が発生した場合の処理
}
・2種類以上の例外をキャッチする
ex. try{ …
}catch(IOException e){
System.out.println("ファイルの書き込みが失敗したときの例外処理");
System.exit(1);
}catch(NullPointerException e){
System.out.println("nullだけだった時の例外処理");
System.exit(2);
}
・例外をザックリ処理する(多態性を使う)
try{
本来の処理
}catch(抽象的な例外クラス 変数名){
例外が発生した場合の処理
}
例外クラスの継承を考えれば、
IOExceptionもNullPointerExceptionもざっくり捉えれば、どちらもException
ex. try{ ….
}catch(Exception e){ ←Exception系の子孫ならどれでもキャッチする
System.out.println("何らかの例外が発生");
}
※ ただこれだとおおざっぱな例外処理になる
☆ fw.close( )のようなファイルを閉じる処理の前に
もし例外が起こってしまい強制終了してしまったら、大変なことになる
(ファイル開けっ放し)
→close( )メソッドのような後片付け処理はどんな時でも必ず実行されないといけない
⇩ そこで….
・try-catch-finally構文 finally→どんな時でも必ず実行される
try{
本来の処理
}catch(例外クラス 変数名){
例外が発生した場合の処理
}finally{
例外があってもなくても必ず実行する処理
}
ファイルを閉じる、開いたデータベースやネットワークの接続を閉じるなどの
「後片付け処理」
→必ずfinally処理を使う