例外処理

例外とは

例外とは、コンパイルはする事は出来るが、プログラムを実行して初めてわかるエラーを認識する為の処理の事。

例外とは、プログラムを実行した時に起きるエラーの事を言う。

例外が発生した時は、プログラムは最後まで実行される事なく、例外が発生した箇所で、途中で終了してしまう。

 

この時、例外処理を行う事により、プログラムを終了させる事無く、例外の内容をより詳しく返す事ができる処理をプログラムに組み込む事ができる。更に、あらかじめ特定の例外が発生した場合、それに合わせた処理内容を記述する事も出来る為、間違いを見つけやすくなったり、修正するコードをプログラムに実装する事もできる。

又、例外が発生するしないにかかわらず必ず処理されるコードを入れる事ができる。

発生する例外がcatchブロックに無い場合は、処理中のメゾットに戻って例外が探される事から、finallyブロックには、必ず行っておきたいコードを記述する。

例外処理

トライtry{}キャッチcatch(){}ファイナリーfinally{}文

try{

  例外を調査するコード

  }

catch(発生する例外の種類名 e){

  例外が発生した時に処理するコード

  }

finally{

  必ず行うコード

           }

※上記コードcatc()内のeは、識別子で任意で設定できる。

 

発生する例外の種類名に関して

 catchブロック内で記述する、発生する例外の種類名は、Throwableクラス(例外クラス)のサブクラスのオブジェクトを戻り値である(識別子e)に代入して受け取っている。識別子eには、発生する例外のクラス名が代入される。

 Throwableクラスのサブクラスには、Exceptionクラスがあり、Exceptionクラスのサブクラスに、ArrayIndexOutOfBoundsExceptionクラスがある。

発生する例外の種類名を、Exceptionと指定した場合、識別子eにはExceptionではなく、例外名の詳細が代入される。

 

◎複数のcatchブロック

catchiブロックは、複数設定する事ができる。これにより、例外クラス毎に違うプログラム処理を記述できる。

 

◎例外クラスの作成

Exceptionクラスを拡張する事により、独自の例外classを作成する事ができる。

1.

例外のクラスを作成

class CarException extends Exception

{

}

CarExceptionはclass名になるので独自に設定できる。

例外クラスは、クラス名を出力するだけなので内容を持たせなくても良い。

2.

main以外のclassのメゾットに例外処理を組み込む。

【構文】

戻り値の型 メゾット名(引数) throws 例外のクラス名

  if(引数の条件){

            例外のclass名 識別子e = new 例外のクラス名; 

             throw e; //※eは修飾子

   }else{

   }

throw eは、例外の戻り値になる。

通常の戻り値は、return 修飾子。

3.

mein classでtry{}catch(CarException){}でエラーが発生した場合受け取る。

main classで2で送出された、例外の戻り値を受け取る為にcatchを使う。

 

 

 

 

 

 

 

 

 

 

lesson11 継承

➀クラスを引き継ぐ

 javaでは、既に作成済みのclassファイルや、javaの中にもともと入っている膨大な量のclassファイルに独自に作成したclassファイルを、付け足す事ができる。その事をクラスの拡張という。拡張する事のメリットは、重複しているメゾットや、フィールドを再度記述する必要がなくなる。拡張した(付け加えた)クラスをサブクラス、もともとあったクラス(付け加えられたクラス)をスーパークラスと呼ぶ。

 

② 拡張の方法

 クラスの宣言の直後に、exteds文を記述し、スーパークラスを拡張する。サブクラス名の後ろに、『extends スーパークラス名』を記述する事により拡張できる。

class Car extends Thread
{
・・・
}

CarクラスをサブクラスにThreadクラスをスーパークラスにした記述。

 

class Taxi extends Car

{
・・・
}

Taxiクラスをサブクラスとし、Carクラスをスーパークラスにした記述。

 

③ 記述例

class Car
{
  public int num;
  public double gas;

  Car(){
    System.out.println("コンスト車を作成");
  }

  public void setNG(int n,double g){
    num = n;
    gas = g;
    System.out.println("ガソリンの量を変更しました。");
  }
}

class Taxi extends Car
{
  private int park;

  Taxi(int p){
    park = p;
  }

  public void setP(int p){
   park = p;
  }

  public void showNGP(){
   System.out.println("ナンバーは"+num+"、ガソリンの量は"+gas+"、駐車場は"+park+"です。");
  }
}

class Sample1
{
    public static void main(String[] args)
    {
        Taxi taxi1 = new Taxi(5);
        taxi1.setNG(4597,40.5);
        taxi1.showNGP();
    }
}

上記コードでは、Car classをスーパークラスとし、Taxi classをサブクラスとしている。main() classをSample1としている。

 

④ コンストラク

継承されるのは、フィールドのみで、コンストラクタは、継承されない。

継承する場合は、

⭕️順序

 main()クラスにおいて、サブクラスをnewによるオブジェクト作成(インスタンス化)を行う際、まずサブクラスのコンストラクタ部分が呼び出される。

サブクラスのコンストラクタの最初は、スーパークラスのコンストラクタが呼び出される(extendsされているから)。これが処理順序になる。

 

:復習:

 コンストラクタは、classがインスタンス化される時に1度だけ呼び出されるメゾット。コンストラクタは、宣言、初期化、代入を一度に行う事ができる。コンストラクタは必ず定義される。

 

classにコンストラクタの記載がない場合は、引数を持たないコンストラクタが呼び出される。

 

mainクラスインスタンス化する際に、引数を定義した場合、サブクラスで定義されている同じ引数のコンストラクタが呼び出される。サブクラスでコンストラクタを呼び出した場合は必ずスーパークラスのコンストラクタが呼び出される。

 

mainクラス

引数あり

 

引数なし

 

 

 

 

 

 

 

 

パッケージ インポート package import

パッケージとは、classを分割して保存する際につける名前の事。

 class毎にコードを分割して保存する場合、同じパッケージ名をつければ、一連のプログラムとして認識される。例えば、main classとその他のclassを分割して保存できる。

一連のプログラムとは、1つのmain classと、1つ以上のclassからできるプログラムの事。

classの前に、『package 名前』をつける。

この時、package名と保存するフォルダ名は同じでなければならない。

すなわち、同じパッケージは、同じフォルダ内に保存する事になる。

package名 = フォルダ名

 

◎main以外のclassファイルとmain classファイルを同じpackageにする場合

1.main以外のclassファイル

先頭にpackage名を記述する。

package pa;
class Car

 

2.mainのclassファイル

package pa;

class Sample1

同一パッケージ内の別のclassファイルの参照を行う(newによるオブジェクトの作成)時、同一パッケージ(フォルダ)であれば、オブジェクトの作成時、classの前にパッケージ名を記述する必要は無い。

Car car = new Car();    →◎

pa.Car car = new pa.Car();   →×

 

◎異なるパッケージにした場合

※パッケージ名が異なるclassファイルを一連のプログラムとして認識させる場合

1.main以外のclassファイル

 各classファイルを、class毎に分割し、さらに異なるフォルダに保存した場合、main以外のclassファイルのコードは、フォルダ間をまたぐので、classの前にpublicをつける。

public class Car

この時、コンストラクタにもpublicをつける。

public Car(){}

記述方法

package pa;
class Car
{

 public Car(){}

}

 ※異なるフォルダに、classファイルを保存する場合も、各フォルダ名と各パッケージ名は一致させなければ参照できない。

 

2.mainのclassファイル

 main classでも、先頭にpackage名を記述する※無名packegeにはしない。異なるpackageのclassファイルで、newによるオブジェクトの作成をする場合、パッケージを指定してオブジェクトを作成する。

pa.Car car = new pa.Car();

記述方法

package pb;

class Sample5
{
  public static void main(String args[])
   {
    pc.Car car1 = new pc.Car();
   }
}

 参照するclassのパッケージ名を、class名の前にドットを入れて記述する。

 

◎無名packege

 そもそも先頭にパッケージ名を記述しない場合、無名のパッケージとなる。無名のパッケージから、パッケージを持ったclassを参照(newによるオブジェクトの作成)する事は出来ない。※クラスライブラリは無名のpackegeからも読み込める。

 無名packageのmain classファイルからpackage名があるclass(無名でない)を呼び出したい場合は、同じフォルダ内に保存し、main classにimport文を記述して読み込ませなければならない。※cdで指定した意外のデレクトリーフォルダよりも上階層のフォルダに、保存したclassファイルは、main classで参照できない。下階層であればアクセスできる。この時、下階層のフォルダをsub packegeと呼ぶ。

 

コンパイルとプログラムの実行

1.デレクトリーの変更(cd)

packageの1階層上のフォルダを指定する。

指定したデレクトリ内にある下階層は全て認識される。

2.コンパイル(javac)

javac  package名¥プログラム名.java

3.実行(java

java  package名.プログラム名

 

 packageは、1つのpackage全体で1つのプログラムと認識するので、ディレクトリはpackageフォルダより、1階層上のフォルダを指定し、javacの後main classを指定する。

 この時、main classが、異なるpacjageのclassを参照(newによるオブジェクトの作成)している場合、main classのある1階層上のフォルダ(1で指定したフォルダ)内または、それよりも下層のフォルダに、参照されるpackageは保存していなければならない。

 

◎import文

 複数のオブジェクトの作成を行わなければならない場合、毎回、package名を記述するのは、コードの先頭に『import パッケージ名.class名;』を記述する。

※import文の記述位置は、mainクラスのpackageの属性を記述した後に入れる。

package pa

import pb.Car;

class Sample1

{

 この時、パッケージ内のすべてのclassファイルを参照する可能性がある場合は、『import パッケージ名.*;』 を記述する。パッケージ名の後ろにclassファイル名は記述せずに、アスタリスクを記述する。

import.pb.*;

  

◎修飾子

private  同じclass内でアクセスできる。

無指定   同じパッケージ内からアクセスできる。

protected  同じパッケージ内と別のclassと別のパッケージクラスのサブクラスからアクセスできる。

public  アクセス制限なし。

 

 

 

スタティックとインスタンス

javanのclass型には、スタティックとインスタンスの2つの概念がある。

 スタティックとは、class型に直接属しているものを指す。classに関連づけられているので、インスタンスオブジェクトを作成せずに、main()クラスから直接呼び出せる。よって、インスタンスオブジェクトに直接関係しない。方定式や三角関数等はスタティックにより作成する。

 

 インスタンスとは、class型には実体はなく、実体を生成する為のコードの事。main()クラスで、newによるインスタンスオブジェクトを作成して初めて実体化される。newによるオブジェクトの作成は、何個でも作成する事ができるので、main()クラス内でclass型の内容が同じで値が違うclassを複数作成する事ができる。classをひな形として捉えると理解しやすい。

 

 スタティック変数(文字列を含む)

スタティック変数は、class内に直接保存している変数の事。

main()クラスでの呼び出し方は、

『クラス名.変数名』

『クラス名.文字列名』

になる。

class名を直接指定して呼び出しを行うので、同名の変数は1つしか存在しない。よって、同じ内容で値が異なるスタティック変数は複数作成できない。

 

 インスタンス変数

インスタンス変数を使用するには、まずnewによる、インスタンスオブジェクトの作成(参照ブログ→インスタンスオブジェクトの作成)を行う。

class型変数の宣言と初期化を行う事により、初めてインスタンス変数をオブジェクトとして実体化し使える様になる。newにより識別子を任意で付けられるので、同じ内容で値が異なるclass型変数を複数作成できる。

 

 スタティックメゾット

 インスタンスに属さない、メゾットになる。スタティック変数に対して、処理を行うメゾットを指す。スタティックメゾットは、newによって宣言初期化代入したインスタンスオブジェクトは一切参照実行ができない。main()メゾットでの呼び出し方は、

クラス名.メゾット名(引数);

になる。

 

 インスタンスメゾット

インスタンスに属するメゾットになる。インスタンス変数を処理するメゾット。newによる初期化が必要になる。

識別子.メゾット名(引数);

となる。

 

インスタンスオブジェクトの作成 基本型とクラス型の変数と配列の比較

●基本型
int num;//宣言 ※int型の変数を用意
num = new int();//初期化 ※1コンストラクタの呼び出しの部分

num = 1;//代入

int num = 1;//短縮
宣言・初期化・代入をまとめられる

基本型は、newによるオブジェクトの作成は不要(できない)。

※1基本型は、メゾット(プログラムにおいての指示そのもの)は無く、フィールド(数値)しか持っていない。コンストラクタは、メゾットの一つである為、コンストラクタの呼び出しは出来ない。結果的にnewによるインスタンスの作成は、行うことができない。よって、この様に記述するとコンパイルできない。

 


●基本型の配列
int num;//宣言【要素の宣言】※int型の配列を用意
num = new int[2];//初期化【要素の確保】※引数分のコンストラクタを呼び出し

num[0] = 1;//代入

int num = new int[i];//短縮
宣言【要素の宣言】・初期化【要素の確保】をまとめられる。
代入はまとめられない。

 


●クラス型の変数
Car num;//宣言 ※Car型の変数を用意
num = new Car();//初期化 ※コンストラクタを呼び出し

 

gas = 40.5;//代入

num = new Car(4597,40.5);//代入 ※コンストラクタで代入
num.set();//代入 ※インスタンスオブジェクトを使用して代入

Car num = new car(引数);//短縮
宣言・初期化・代入をまとめられる。

 


●クラス型の配列
Car num;//宣言【要素の宣言】※int型の配列を用意
num = new Car[2];//初期化【要素の確保】※引数分のコンストラクタを呼び出し

num[0] = new Car();//代入

Car num = new Car[2];//短縮
宣言【要素の宣言】・初期化【要素の確保】をまとめられる。
代入はまとめられない。


【まとめ】
クラス変数(配列)宣言→クラス配列の要素の確保→

クラス変数(配列)の初期化(コンストラクタの呼び出し)

------ここで、インスタンスオブジェクトの作成完了-------

→数値の代入

を考えながらコードを記述していく。

lesson7 配列

①配列とは

 変数は、1つの数値を入れておく「箱」に、データ型と名前をつけた「1つの入れ物」。 

 配列は、「1つの入れ物」が横に連なって並んでいる「箱の列」。箱の列には、データ型と名前をつける。また、配列の各箱には、0から始まる番号が順に振られて区別される。配列は参照型になる。

 

②宣言と初期化

int test;

 「配列の宣言」は、上記コードで行う。このコードでは、データ型intでtestという名前の配列を準備するという意味。要素の宣言。

 

test = new int[i];

 「配列の初期化」は、上記コードで行う。このコードでは、testという宣言済みの配列の中にi個の変数を準備する意味。要素の確保とも言う。※必ずnewをつける。

基本型の変数の場合は不要。

int test = new int [i];

 「配列の宣言と初期化」(要素の確保)は上記コードの様に1度に行う事ができる。この時データ型は統一する。

 

③代入

 配列の要素を確保できたら、配列の各変数に数値を代入する。

int test = new int[3];

test[0] = 50;

test[1] = 45;

test[2] = 65;

 

 上記のコード以外にも、下記のコードでも数値を代入できる。「test[0]」の0部分を添字または、インデックスと呼ぶ。

【注意】

 上記のコードでは、test[0]からtest[2]までのインデックスが貼られている。0から始まる為、要素の確保時に指定した引数「 new int[3] 」より、実際に作られる最後のインデックスは、-1になる。この時、配列の要素の確保が足らない時は、コンパイルは通るが、実行画面でエラーが起きる。

 

int test = {50,45,65,};

これは、一括して宣言から要素の確保し代入まで行う。

 

④配列と相性の良いfor文

識別子に引数を持つ配列変数は、for文と組み合わせる事により、宣言の記述や、キーボードから文字を入力するコードの記述を短縮する事ができる。

 基本型の変数(int num1やdouble dou2)は、数値を代入する際は、一つ一つを宣言し代入していかなければならない。識別子に引数を持たないのでfor文は使えない。よって毎回、

num1=

num2=

.......

と記述しなければならなかった。

 対して、配列では識別子に引数がある。よってfor文を用いてコードを短略できる。

import java.io.*;

class Sample1

{

      public static void main(String args)throws IOException

   {

       System.out.println("配列を作します。作成する配列の数を入力して下さい。");

       BufferedReader br =

          newBufferedReader(new InputStreamReader(System.in,"SJ I S"));

 

        String str1 = br.readLine();

         int num1 =  Integer.parseInt(str1);

         int  test = new int[num1];

          //int型の配列をnum1個の宣言

 

        for(int i = 0; i <test. length;i++){

           String str = br.readLine();

           test[i] =  Integer.parseInt(str);

           System.out.println("test"+ i +"は"+test[i]+"です。");

     }

  }

}

 

⑤参照型

 配列は参照型である。参照型とは、実際の数値を格納しているのではなく、場所の位置のみを参照している型の事。例えば下記のコードは、int型配列の0番初めに5を代入したという記述になる。

int[0]=5

int[0]は実際に5を格納しているのではなく、5を格納している場所(アドレス)を格納している。

参照型の特徴の1つとして、配列同士を代入した際は数値がもう一つ作られるのではなく、代入した配列を参照(指している)という事になる。よって、代入した配列の参照先が変われば、代入された方も変わる事となる。

class Sample1

{

   public static void main(String args)

   {

     int num1 = new int[2];

     int num2 = new int[2];

     num1[0] = 5;

     num1[1] = 10;

 

     num2 = num1;//※1

 

     num1[0] = 15;

     System.out.println("num1[0]は"+num1[0]+"です。");

     System.out.println("num2[0]は"+num2[0]+"です。");

      }

}

上記コードの場合、両方とも15が出力される。配列は、実際の格納ではなく参照なので、※1の代入演算子によりnum2はnum1に関連付けられた事になり、num2は num1を指し示す。よって指し示しているnum1に変更があれば、num1を指し示しているnum2も変更されるという仕組みになっている。当然、 num2ではなく直接数値等を代入した際は、代入した数値を指し示しているので、num2に影響されない。

 

⑥多次元配列

 これまでの配列は1列であった。この1列の配列要素の中に、さらに配列要素を組み込む事ができる。int[0]の中にさらに配列を入れる。2次元配列であれば、エクセルの様なワークシートをイメージする。

2次元配列の宣言(要素の確保)

int test;//要素の宣言

new int[3][4];//要素の確保

上記コードは、3個の各配列要素の中に4個の配列要素を組み込んだ配列を準備したという事になる。エクセルで言うと横3セル縦4セルの合計12セルを準備した事となる。また、下記の様に1行でも示せる。

int test = new int[3][4];//要素の宣言と確保

 

2次元配列の代入

1次配列と同じ様に下記の様に代入できる。1次配列と同様に最初はインデックス(添字)は0から始まる。

int[0][0] =1;

int[0][1] =2;

int[0][2] =3;

int[0][3] =4;

int[1][0] =5;

・・・

・・・

int[2][2] =11;

int[2][3] =12;

1つ1つ代入していく事もできるが、要素の確保と代入をカッコでくくり、一括して行う事もできる。

int test1 ={{1,2,3,4},{5,6,7,8},{9,10,11,12}};

カッコがたくさんありややこしい様に見えるが、1列の配列要素の中に、さらに配列要素を組み込んでいて枝分かれしていると認識すれば理解しやすい。

上記コードは、要素int[3][4]になる。

int[0][0]が1  int[1][0]が5  int[2][0]が9

        [1]が2           [1]が6          [1]が10

        [2]が3           [2]が7          [2]が11

        [3]が4           [3]が8          [3]が12

になる。

int[] test1 ={ {int[0]} , {int[1]} , {int[2]} };

各、int[0]~int[2]までの配列の中にさらに配列をネストしていると考える。

この様に考えると、2次元以上の配列もint[0][0]の中に更に配列が組み込まれている事を理解する。型を暗記しコードを書ける様にするのではなく、しくみを理解してアウトプットを継続的に行う事により初めて使える様になる。

 

多次元は配列での.length

多次元配列でも配列要素を調べる為に.lengthを使用する事ができる。1次配列の配列の要素を調べる場合は、『添字識別子.length』であった。

多次元配列の場合は、『添字識別子[添字].length』で配列要素を調べられる。上記の配列test1の場合、『test[0].length;』は、

test[0][0]

test[0][1]

test[0][2]

test[0][3]

の要素を調べるので、4になる。

この時、『test.length;』とした場合は

test[0]

test[1]

test[2]

の要素が調べれるので、3となる。

 

 

Mathメゾット

Mathクラスのメゾットの多くは、クラスに直接属するクラス変数に数値を代入して計算を行う。よってメゾットは、クラスメゾット(staticメゾット)でnewによるオブジェクトの作成は不要になる。直接クラス名を呼び出す。

Mathメゾットは、主に計算を行う為のメゾットである。

double dou;

int num1 = 1;

int num2 = 59;

int num3 = -39;

double dou1 = 0.5;

double dou2 = 12.5;

double dou3 = -30.1;

 

Q1

 double型または、int型の引数の絶対値をdouble型または、int型で返す。 

クラスメゾットを記述し、mainクラスでメゾットを呼び出すコードを記述。

 

 

 

A1

static double abs(double a)

static int abs(int a)

double dou = Math.abs(dou3);

int num = Math.abs(num3);

 

Q2

  double型の引数以上で、最も近い整数をdouble型で返す。

クラスメゾットを記述し、mainクラスでメゾットを呼び出すコードを記述。

 

 

A2

static double ceil(double a)

double dou = Math.ceil(dou1);

引数の小数点以下を繰り上げてdouble型で返す。引数が負の値の時は、小数点以下が切り捨てになる。

int num =(int) Math.ceil(dou1);

int型にしたい場合は、キャスト演算を使い明示するとint型で数値を受け取れる。

 

Q3

 double型の引数以下で、最も大きい整数をdouble型で返す。クラスメゾットを記述し、mainクラスでメゾットを呼び出すコードを記述。

 

 

A3

static double floor(doudle a)

dou = Math.floor(dou2) ;

引数の小数点以下を切り捨てdouble型で返す。

引数が負の値の場合は、小数点以下が繰り上げになる。int型にしたい場合は、キャスト演算を使用し明示する。

int num = (int) Math.floor(dou2);

 

Q4

 2つのdouble型またはint型の引数のうち大きい方をdouble型で返す。

クラスメゾットを記述し、mainクラスでメゾットを呼び出すコードを記述。

 

 

 

A4

static double max(double a, double b)

static double max(int a, int b)

double bou = Math.max(dou1,dou2);

引数に関しては、int型でもdouble型でも良い。

int型で数値を得たい場合は、キャスト演算を使用し明示する。

int num = (int) Math.max(dou1, nam1);

引数を2個以上設定するとエラーが起きる。

 

 

Q5

 2つのdouble型またはint型の引数のうち小さい方をdouble型で返す。クラスメゾットを記述し、mainクラスでメゾットを呼び出すコードを記述。

 

 

A5

static double min(double a, double b)

static double min(int a, double b)

double dou = Math.min(num1,dou1);

引数を2個以上設定するとエラーが起きる。

 

Q6 1番目の引数を2番目の引数で累乗した結果をdouble型で返す。

 

 

static double pow(double a, double b)

double dou = Math.pow(dou1,dou2);

累乗とは、dou1のdou2乗という事。

 

7 0.0~1.0未満までの数値をランダムにdouble型で返す。

 

 

static double random()

double = Math.random();

少数点以下を返すので、整数を返す値にするには、四数関数とキャスト演算を使用しする。

例えばnumにサイコロの数値(1から6)をランダムに代入する場合は以下の様に記述する。

int num = (int) (Math.random()*6)+1;

0.99*6 ==  5.9399999999999995

(int)のキャスト演算は、小数点以下は切り捨てられる。

 

8 double型の最も近い整数値をdouble型で返す。

 

 

static double rint(double a)

double dou = Math.rint(dou1);

1.49は1.0で返される。

1.50は2.0で返される。