課題:第1回Java試験問題の解答を解説し、その動作について考察せよ。    併せて、講義資料オブジェクト指向プログラムJava1の中のサンプルプログラムについて考察せよ。
    学籍番号 035735k     氏  名 仲松義嗣     学  部 情報工学部

-----第1回Java試験問題の解答の解説-----

01:Javaのソースファイル(Sample.java)をコンパイルせよ。 解答: javac Sample.java 02:Javaソースファイル(Sample.java)をコンパイルした後にできるファイル名を述べよ。 解答: Sample.class 03:Javaコンパイラに対して、実行時に使われるjavaコマンドは何と言うか述べよ。 解答: インタプリタ 04:Javaアプリケーションに対して、Webブラウザ上で動作するプログラムを何と言うか述べよ。 解答: Javaアプレット 05:Webブラウザ上で動作するJavaプログラムを他の方法で実行するコマンドは何と言うか述べよ。 解答: appletviewer 06:サーバ上で動作するJavaプログラムを何と言うか述べよ。 解答: Javaサーバサイドプログラム 07:メインメソッドを定義せよ。 解答: public staitc void main(String args[]){} 08:標準出力を使用し、"Hello"のみ出力せよ。 解答: System.out.print("Hello"); 09:Java言語には含まれていない予約語を2つ述べよ。 解答: goto const 10:char型のサイズと保持できる値を述べよ。 解答: 16bit Uniコード 11:データ型として整数を保持できる型を4つ述べよ。 解答: byte int short long 12:参照型を2つ述べよ。 解答: 配列 クラス 13:文字列や数値の連結ができる演算子を述べよ。 解答: 文字列連結演算子 14:実行のフローを分岐させる制御文を2つ述べよ。 解答: if switch 15:反復処理を行う制御文を3つ述べよ。 解答: for while do-while 16:例外処理を行う制御文を述べよ。 解答: throw 17:配列の生成で使用されるキーワードを述べよ。 解答: new 18:int型の配列名aの宣言方法を2つ述べよ。 解答: int[] a = new int(); int a[] = new int(); 19:配列名aの要素数(大きさ)を述べよ。 解答: a.length 20:concatメソッドのクラスを述べよ。 解答: java.lang.String 21:int[] a = {}; の要素数を数値で述べよ。 解答: 0 22:int型変数numが100で割り切れるかどうかを判断する制御文を述べよ。 解答: if(num%100 = 0) 23:int型変数yearが、閏年かどうかを判断する条件式を述べよ。 (閏年:4で割れ100で割り切れないが、400で割り切れる年) 解答: ((year%4=0)&&(year%100!=0)||(year%400=0)) 24:次のコードを実行した後の出力値を述べよ。

01: int x,y; 02: x = 100; 03: x += 1; 04: x--; 05: y = 200 + x; 06: System.out.println(y++);

解答: 300 解説: 06:yの評価が行われた後に、インクリメントが実行される。 25:次のコードを実行した後の出力値を述べよ。

01: int a=0, x=0; 02: a = 5; 03: a += 3; 04: x = ++a; 05: System.out.println(x);

解答: 9 解説: 04:インクリメントされたaをxに代入している。 26:次のコードを実行した後の出力値を述べよ。

01: int a=9, b=3; 02: a /= b; 03: System.out.println(a %= b);

解答: 0 解説: 02:aをbで割った商をaに代入しています。 03:aをbで割った余りを出力します。 26:次のコードを実行した後の出力値を述べよ。

01: int i, j; 02: for(i=0,j=0; i<3; i++) ++j; 03: System.out.println(i * j);

解答: 9 解説: 02:i=2のとき、i<3を満たしているので、インクリメントされる。 結果として、i=3,j=3となる。    03:i * j の値を出力します。 27:次のコードを実行した後の出力値を述べよ。

01: int i=2; 02: while(i-- > 0) 03: System.out.print(i);

解答: 10 解説: 02:2>0より条件を満たす。その後にデクリメントされて、出力。 1>0より条件を満たす。その後にデクリメントされて、出力。 28:次のコードを実行した後の出力値を述べよ。

01: int num=10000; 02: for(int i = 0; i < 4; i++) 03: num >>= i; 04: System.out.println(num);

解答: 156 解説: 02~03:numを2進数に直した値を6bitシフトさせ、numに代入します。 04:10進数に直したnumを表示します。 結局10000を2の6乗で割った商を表示しています。 29:次のコードを実行した後の出力値を述べよ。

01: int num = 0; 02: for(int i = 1; i <=10; i++) 03: if(++num % i == 0) 04: num++; 05: System.out.println(++num);

解答: 12 解説: 02:制御変数iを1に初期化する。 03~04:numをインリメントした値がiで割りきれたら、numをインクリメントする。 05:インクリメントしたnumを表示します。 30:次のコードを実行した後の出力値を述べよ。

01: int a = 9; 02: if(a++ != 10 | a++ == 10) 03: a++; 04: System.out.println(a);

解答: 12 解説: 02:if文の中の条件式で2回インクリメントされています。 03~04:インクリメントしたaを表示します。

-----講義資料サンプルプログラムの考察-----

File name: Demo.java

01:class CircleC { // クラス 02: double pai = 3.14; // データ 03: double circle(int r) { // メソッド 04: return pai * r * r; 05: } 06:} 07: 08:class Demo { // クラス 09: public static void main(String args[]) { // メソッド 10: double area;; 11: CircleC obj; // オブジェクト 12: obj = new CircleC(); 13: area = obj.circle(10); 14: System.out.println("area = " + area); 15: } 16:}

実行結果 area = 314.0 考察:11:01~06で定義したクラス型のオブジェクト変数を作っています。     12:コンストラクタをCircleC()に指定しています。     13:CircleC型のobjからcircle(int r)メソッドを呼び出しています。      引数はint型の半径で、戻り値はdouble型の面積です。     そして、その値をdouble型のareaに代入します。 File name: Keisan.java

01:class Comp4 { // クラスComp4を定義 02: int add(int x, int y) { // メソッドadd(intx,int y)を定義 03: return x + y; // x + y を返す 04: } 05: int substract(int x, int y) { // メソッドsubstractを定義 06: return x - y; // x - y を返す 07: } 08: int multiply(int x, int y) { // メソッドmultiplyを定義 09: return x * y; // x * y を返す 10: } 11: int divide(int x, int y) { // メソッドdivideを定義 12: return x / y; // x / y を返す 13: } 14:} 15: 16:public class Keisan { 17: public static void main(String args[]) { 18: int a, b, wa, sa, seki, sho; 19: Comp4 enzan = new Comp4(); //クラスComp4のオブジェクトenzan作成 20: 21: a = 20; 22: b = 10; 23: wa = enzan.add(a, b); // オブジェクトenzanのadd(a,b)を実行 24: sa = enzan.substract(a, b); // 同上のsubstract(a,b)を実行 25: seki = enzan.multiply(a, b); // 同上のmultiplu(a,b)を実行 26: sho = enzan.divide(a, b); // 同上のdivide(a,b)を実行 27: System.out.println(a + " + " + b + " = " + wa); 28: System.out.println(a + " - " + b + " = " + sa); 39: System.out.println(a + " * " + b + " = " + seki); 30: System.out.println(a + " / " + b + " = " + sho); 31: } 32:}

実行結果 20 + 10 = 30 20 - 10 = 10 20 * 10 = 200 20 / 10 = 2 考察:01~14:Comp4クラスで2つの引数をとり和の計算をするadd(int x,int y) 差の計算をするsubstruct(int x,int y),積の計算をするmultiply(int x,int y) 商の計算をするdivide(int x,int y)の4つのメソッドを定義しています。 19:Comp4型のオブジェクト変数enzanをComp4()コンストラクタで作っています。 File name: VarSample.java

01:class Display { 02: int n //クラス変数 03: void Disp() { 04: int i; //ローカル変数 05: for (i = 1; i <= n; i++) 06: System.out.print(I + " "); 07: } 08: 09: class VarSample { 10: public static void main(String args[]) { 11: Display obj = new Display(); //クラスDisplayのオブジェクトobj生成 12: obj.n = 10; //オブジェクトobjの数nに10を代入 13: obj.Disp(); //オブジェクトobjのDisp()実行 14 } 15:}

実行結果 1 2 3 4 5 6 7 8 9 10 考察:01~07:Displayクラスのフィールドn(クラス変数)、メソッドDisp()が書かれています。     09~15:Displayクラスのオブジェクトを作成し、Displayクラスを呼び出すVarSampleクラスが書かれています。        VarSampleクラスからはDisplayクラスのメソッド内で定義された変数(ローカル変数)        にはアクセスできないようになっています。 File name: SumSample1.java

01:class Sum { 02: int total; 03: Sum() { // コンストラクタ(クラス名と同名) 04: total = 0; // 0 クリア 05: } 06: void add(int x) { 07: total += x; 08: } 09:} 10: 11:class SumSample { 12: public static void main(String args[]) { 13: Sum obj1 = new Sum(); // クラスSumのオブジェクトobj1生成 14: Sum obj2 = new Sum(); // クラスSumのオブジェクトobj2生成 15: 16: obj1.add(10); 17: obj1.add(20); 18: obj2.add(30); 19: obj2.add(40); 20: System.out.println("obj1.total = " + obj1.total); 21: System.out.println("obj2.total = " + obj2.total); 22: } 23:}

実行結果 obj1.total = 30 obj2.total = 70 考察:02:static修飾子を付けていないint型のフィールドtotalを宣言します。     03~05:クラス名と同じ名前のSum()コンストラクタを作成します。     13:Sum型のオブジェクト変数obj1を作成。     14:Sum型のオブジェクト変数obj2を作成。     16~17:obj1のメソッドadd(int x)を呼び出しています。     18~19:obj2のメソッドadd(int x)を呼び出しています。     実行結果より、obj1のtotalフィールドとobj2のtotalフィールドのメモリ領域が違うことがわかります。 File name: SumSample2.java

01:class Sum { 02: static int total; // 値を共有させる 03: Sum() { // コンストラクタ(クラス名と同名) 04: total = 0; // 0 クリア 05: } 06: void add(int x) { 07: total += x; 08: } 09:} 10: 11:class SumSample { 12: public static void main(String args[]) { 13: Sum obj1 = new Sum(); // クラスSumのオブジェクトobj1生成 14: Sum obj2 = new Sum(); // クラスSumのオブジェクトobj2生成 15: 16: obj1.add(10); 17: obj1.add(20); 18: obj2.add(30); 19: obj2.add(40); 20: System.out.println("obj1.total = " + obj1.total); 21: System.out.println("obj2.total = " + obj2.total); 22: } 23:}

実行結果 obj1.total = 100 obj2.total = 100 考察:02:static修飾子付きのint型のフィールドtotalを宣言します。    13:Sum型のオブジェクト変数obj1を作成。     14:Sum型のオブジェクト変数obj2を作成。     16~17:obj1のメソッドadd(int x)を呼び出しています。     18~19:obj2のメソッドadd(int x)を呼び出しています。     実行結果より、obj1のtotalフィールドとobj2のtotalフィールドのメモリ領域が共有されていることがわかります。     SumSample1.javaとSumSample2.javaよりstatic修飾子を付けることによりメモリ領域が共有されていると言えます。 File name: ConstructSample.java

01:class Sum { 02: int total; 03: Sum() { // コンストラクタ 引数無し 04: total = 0; 05: } 06: Sum(int x) { // コンストラクタ 引数 x 07: total = x; 08: } 09: void add(int x) { 10: total += x; 11: } 12:} 13: 14:class ConstrcSample { 15: public static void main(String args[]) { 16: Sum obj1 = new Sum(); // クラスSumのオブジェクトobj1生成 17: obj1.add(10); 18: obj1.add(20); 19: System.out.println("sum1 = " + obj1.total); 20: 21: Sum obj2 = new Sum(100); // クラスSumのオブジェクトobj2生成 22: obj2.add(10); 23: obj2.add(20); 24: System.out.println("sum2 = " + obj2.total); 25: } 26:}

実行結果 sum1 = 30 sum2 = 130 考察:03~05:引数なしのSum()コンストラクタを作成。     06~08:int型の引数を取るSum(int x)コンストラクタを作成。     Sum()とSum(int x)は変数totalの初期値が違います。     16:Sum型のオブジェクト変数obj1をSum()コンストラクタで宣言。     21:Sum型のオブジェクト変数obj2をSum(int x)コンストラクタで宣言。 File name: StaticSample.java

01:class Disp { 02: static { // static イニシャライズ 03: System.out.println("initialize"); 04: } 05: Disp() { // コンストラクタ 06: System.out.println("construct"); 07: } 08:} 09: 10:class StaticSample { 11: public static void main(String args[]) { 12: Disp obj1 = new Disp(); //オブジェクト生成時にコンストラクタを処理 13: Disp obj2 = new Disp(); //オブジェクト生成時にコンストラクタを処理 14: } 15:}

実行結果 initialize // Dispクラスのロード時に処理 construct // Disp.obj1 = new Disp(); が実行されるときに処理 construct // Disp.obj2 = new Disp(); が実行されるときに処理 考察:02~04:static{}の中に System.out.println("initialize"); 。 05~07:Disp(){}の中に System.out.println("construct"); 。     12~13:Disp型のオブジェクト変数obj1をDisp()で宣言。この時、System.out.println("construct"); が処理されます。 実行結果より、StaticSampleクラスで呼び出してもいないstatic{}の中の System.out.println("initialize"); が     Disp(){}の中の System.out.println("construct"); より早く処理されています。     したがって、static{}の中に書いたメソッドは全てのコンストラクタより早く処理されることが分かります。 File name: OverloadSample.java

01:class Display { 02: void Disp() { // メソッド Disp 引数なし 03: System.out.println("Nothing"); 04: } 05: void Disp(int x) { // メソッド Disp 引数 x 06: System.out.println(x); 07: } 08: void Disp(int x, int y) { // メソッド Disp 引数 x, y 09: System.out.println(x + y); 10: } 11:} 12: 13:class OvldSample { 14: public static void main(String args[]) { 15: Display obj = new Display(); // クラスDisplayのオブジェクトobj生成 16: obj.Disp(); // オブジェクトobjのDisp()を実行 17: obj.Disp(1); // オブジェクトobjのDisp(1)を実行 18: obj.Disp(1, 2); // オブジェクトobjのDisp(1,2)を実行 19: } 20:}

実行結果 Noting 1 3 考察:02~04:引数なしのDisp()メソッドを作成。     05~07:int型の引数を1つ取るDisp(int x)メソッドを作成。 08~10:int型の引数を2つ取るDisp(int x,int y)メソッドを作成。     15:Display型のオブジェクト変数objをクラス名のDisplay()コンストラクタを使って作成しています。 このobj変数から全てのメソッドにアクセスできます。 16~18:実際に、objから違う引数をとるメソッドにアクセスしています。 File name: PrivateSample.java

01:class keisan { 02: static int tanka; 03: private float rate; // private変数rateの宣言 04: 05: keisan() { // コンストラクタ 06: tanka = 1000; 07: rate = 0.05f; 08: } 09: int keisan(int kazu) { 10: int kingaku; 11: kingaku = (int)(tanka * kazu * (1.0 + rate)); 12: return kingaku; 13: } 14:} 15: 16:class PrvSample { 17: public static void main(String args[]) { 18: keisan obj1 = new keisan(); 19: 20: int kazu = 3; 21: int kingaku = obj1.keisan(kazu); 23: 22: System.out.println("tanka = " + obj1.tanka); 23: System.out.println("kazu = " + kazu); 24: System.out.println("kingaku = " + kingaku); 25: //System.out.println("rate = " + obj1.rate); //private変数のため参照不可 26: } 27:}

実行結果 tanka = 1000 kazu = 3 kingaku = 3150 考察:02:static修飾子を付けたint型の変数tankaを宣言。     03:private修飾子を付けたfloat型の変数rateを宣言。     05~08:引数を取らないkeisan()コンストラクタの作成。     09~13:int型の引数を1つ取りint型で値を返すkeisan(int kaza)コンストラクタの作成。  18:keisan型のオブジェクト変数obj1をクラス名のkeisan()コンストラクタで作成。     20:クラス変数kazuに3を代入しています。     21:クラス変数kingakuに(tanka * kazu * (1.0 + rate))をint型にキャストした値を代入しています。     25:private修飾子を付けたrate変数をPrvSampleクラスから直接呼び出そうとするとコンパイルを通してもらえません。     rate変数に対するアクセスに制限を付けることで、間違えてrate変数を書き換えてしまうことを防ぐのに使えそうです。

-----感想・反省-----

 今回のレポートはいろいろ手抜きをしていまいました。 次回はもう少し早めにとりかかりたいです。