inner class
■内部クラス
クラス内に宣言されたクラスのこと
+クラス間の関係を明確に出来る
あるクラスのメンバ変数やメソッドに強く依存しているクラスを そのクラスの内部クラスとして宣言
ゆうのが一般的
*メンバ変数、メソッド等と同じように、クラスの構成要素の一つ
→private protected public等のアクセスレベルを付与できる。
*内部クラスから同じクラス内のprivateなメンバ変数、メソッドも参照できる。
*メソッド内に内部クラスの宣言も可
※その内部クラスは、メソッド内でのみ機能し、同じクラスのメンバ変数やメソッドの参照は不可。
※その内部クラスからは、メソッド内のfinal修飾子が付与されたローカル変数のみ参照できる。
--------------------------------------------------
class OuterClass {
private String outerMsg = "OuterClassクラスのメンバ変数";
public static void main(String[] args) {
OuterClass outer = new OuterClass();
outer.exeClass();
}
private class InnerClass {
private String innerMsg = "InnerClassクラスのメンバ変数";
//(2)
void inMethod() {
System.out.println(outerMsg);
System.out.println(innerMsg);
}
}
void exeClass() {
InnerClass inner = new InnerClass();
inner.inMethod();
}
}
--------------------------------------------------
■無名クラス
内部クラスの一種
クラス名がない内部クラスのこと
+新たなクラス宣言をせずに、メソッド内で抽象クラス、インタフェースを実装できる
抽象クラスやインタフェースの実装で利用するのが一般的
※無名クラスの利用は、可読性を保持する為に、実装が極めて単純なものに止めるべき。
*無名クラスの宣言だけでなく、オブジェクト生成も可。
new AbsClassType() { 無名クラス }
new IFClassType() { 無名クラス }
--------------------------------------------------
interface ExInter {
void sayHello(int x);
}
class HelloInter {
public static void main(String[] args) {
//mainメソッド内で無名クラスを使用し、ExInterインタフェースを実装
ExInter object1 = new ExInter () {
public void sayHello(int x) {
//sayHelloメソッドの実装
}
};
object1.sayHello(5);
}
}
--------------------------------------------------
ref:
http://www.javaroad.jp/java_class15.htm
クラス内に宣言されたクラスのこと
+クラス間の関係を明確に出来る
あるクラスのメンバ変数やメソッドに強く依存しているクラスを そのクラスの内部クラスとして宣言
ゆうのが一般的
*メンバ変数、メソッド等と同じように、クラスの構成要素の一つ
→private protected public等のアクセスレベルを付与できる。
*内部クラスから同じクラス内のprivateなメンバ変数、メソッドも参照できる。
*メソッド内に内部クラスの宣言も可
※その内部クラスは、メソッド内でのみ機能し、同じクラスのメンバ変数やメソッドの参照は不可。
※その内部クラスからは、メソッド内のfinal修飾子が付与されたローカル変数のみ参照できる。
--------------------------------------------------
class OuterClass {
private String outerMsg = "OuterClassクラスのメンバ変数";
public static void main(String[] args) {
OuterClass outer = new OuterClass();
outer.exeClass();
}
private class InnerClass {
private String innerMsg = "InnerClassクラスのメンバ変数";
//(2)
void inMethod() {
System.out.println(outerMsg);
System.out.println(innerMsg);
}
}
void exeClass() {
InnerClass inner = new InnerClass();
inner.inMethod();
}
}
--------------------------------------------------
■無名クラス
内部クラスの一種
クラス名がない内部クラスのこと
+新たなクラス宣言をせずに、メソッド内で抽象クラス、インタフェースを実装できる
抽象クラスやインタフェースの実装で利用するのが一般的
※無名クラスの利用は、可読性を保持する為に、実装が極めて単純なものに止めるべき。
*無名クラスの宣言だけでなく、オブジェクト生成も可。
new AbsClassType() { 無名クラス }
new IFClassType() { 無名クラス }
--------------------------------------------------
interface ExInter {
void sayHello(int x);
}
class HelloInter {
public static void main(String[] args) {
//mainメソッド内で無名クラスを使用し、ExInterインタフェースを実装
ExInter object1 = new ExInter () {
public void sayHello(int x) {
//sayHelloメソッドの実装
}
};
object1.sayHello(5);
}
}
--------------------------------------------------
ref:
http://www.javaroad.jp/java_class15.htm
nested class
■ネストクラス
クラス中に記述されたクラスのこと
→入れ子状のクラス
■分類
ネストクラスは付与される修飾子によって分類される。
ネストクラス
|―インナークラス(内部クラス)
| |―ローカルクラス(ローカル内部クラス)
| |―非staticメンバクラス
| |―匿名クラス(無名クラス)
|―staticメンバクラス
ref:
http://sjc-p.obx21.com/word/jn/nestedclass.html#main
クラス中に記述されたクラスのこと
→入れ子状のクラス
■分類
ネストクラスは付与される修飾子によって分類される。
ネストクラス
|―インナークラス(内部クラス)
| |―ローカルクラス(ローカル内部クラス)
| |―非staticメンバクラス
| |―匿名クラス(無名クラス)
|―staticメンバクラス
ref:
http://sjc-p.obx21.com/word/jn/nestedclass.html#main
[J2SE1.4] スレッド2
排他制御
・synchronizedメソッドを使った排他制御
・synchronizedブロックを使った排他制御
[synchronizedメソッドを使った排他制御]
アクセス修飾子+synchronized+戻り値+メソッド名(引数リスト){...}
synchronizedメソッドには
非staticなものとstaticなもの
がある
・非staticなsynchronizedメソッド
synchronizedメソッドにあるスレッドにアクセスすると、
他のスレッドはこのメソッドにはアクセス出来なくなる。
→先にアクセスしたスレッドの処理が終わるまで待つ。
import java.util.ArrayList;
public class Monitor {
private ArrayList list = new ArrayList();
public synchronized void addObj(Object obj) {
list.add(obj);
}
}
Thread1がaddObjを実行中の間、
Thread2はaddObjにアクセス出来ない。
複数スレッドからアクセスされるオブジェクトを
スレッドプログラミングで[モニタ]という。
import java.util.ArrayList;
public class Monitor {
private ArrayList list = new ArrayList();
public synchronized void addObj(Object obj) {
list.add(obj);
}
public synchronized void removeObj(int idx) {
list.remove(idx);
}
public void getSize(int idx) {
list.size(idx);
}
}
Thread1がaddObjを実行中の間、
Thread2はremoveObjにもアクセス出来ない。
1つのsynchronizedメソッドが実行されている場合、
そのクラスに存在する全てのsynchronizedメソッドにロックがかかる。
クラス内の全てのsynchronizedメソッドは、シンクロし合って1セットとなる。
ただし、
synchronizedキーワードがついていない部分は排他制御の対象外
Thread1がaddObjを実行中の間も、
Thread2はgetSizeを実行できる。
要注意
フィールドlistを扱うメソッドaddObjとremoveObjにsynchronizedをつけても、
フィールドlist自体にロックがかかっていないので、
private以外のアクセス修飾子の、synchronizedでないメソッドでlistに意図せぬ変更をし得る。
・staticなsynchronizedメソッド
import java.util.ArrayList;
public class Monitor {
private static ArrayList list = new ArrayList();
public static synchronized void staticAddObj(Object obj) {
list.add(obj);
}
public static synchronized void staticRemoveObj(int i) {
if (i < list.size()) {
list.remove(i);
}
}
public synchronized void addObj(Object obj) {
list.add(obj);
}
public synchronized void removeObj(int i) {
if (i < list.size()) {
list.remove(i);
}
}
}
Thread1がstatidAddObjを実行中の間、
Thread2は
staticAddObjとstaticRemoveObjにはアクセス出来ないが、
addObjとremoveObjにはアクセス出来る。
Thread1がaddObjを実行中の間、
Thread2は
addObjとremoveObjにはアクセス出来ないが、
staticAddObjとstaticRemoveObjにはアクセス出来る。
非staticなsynchronizedメソッド同士
staticなsynchronizedメソッド同士
でシンクロする。
[synchronizedブロックを使った排他制御]
synchronizedメソッドでの排他制御:
全てのメソッドが対象になり、1クラスに1種類の排他制御しか出来ない。
synchronizedブロックでの排他制御:
多彩な排他制御の範囲を指定でき、複雑な排他制御も出来る。
synchronizedブロックの記述方法
synchronized (OBJECT) { ...... }
※OBJECT:
ロック用オブジェクト
synchronizedブロックを実行する為の権利みたいなもの
ロック用オブジェクトはObjectインスタンスでもStringインスタンスでも何でも可。
01:import java.utilArrayList;
02:public class Minitor {
03: public static ArrayList list = new ArrayList();
04: private Object lockObj = new Object();
05: public void addObj(Object obj) {
06: synchronized(lockObj) {
07: list.add(obj);
08: }
09: }
10:}
6行目でロック(ロックフラグ)を取得したスレッドのみが
synchronizedブロックの処理を続行できる。
Thread1がsynchronizedブロックを処理している間、
Thread2はlockObjを取得出来ないのでsynchronizedブロックを処理できない。
メソッド全体を排他制御の対象とするよりも、
メソッドの一部分だけを排他制御の対象とした方が、
排他制御の範囲を最小限に出来るため、パフォーマンスも上がる。
synchronizedブロックで複数種類の排他制御の実装
import java.util.ArrayList;
public class Monitor {
public static ArrayList list1 = new ArrayList();
public static ArrayList list2 = new ArrayList();
private Object lockObj1 = new Object();
private Object lockObj2 = new Object();
public void addObj1(Object obj) {
synchronized(lockObj1) {
list.add(obj);
}
}
public void addObj2(Object obj) {
synchronized(lockObj2) {
list.add(obj);
}
}
public synchronized void removeObj1(int i){
synchronized(lockObj1){
if(i < list.size()){
list1.remove(i);
}
}
}
public synchronized void removeObj2(int i){
synchronized(lockObj2){
if(i < list.size()){
list1.remove(i);
}
}
}
}
lockObjectはなんでもよい
import java.util.ArrayList;
public class Monitor {
public static ArrayList list = new ArrayList();
public void addObj1(Object obj){
synchronized(this){
list.add(obj);
}
}
public int getSize(Object obj){
return list.size();
}
}
単にロックオブジェクトが[this]なだけ。
synchronizedブロック内を実行中の間は、
他のスレッドが自分自身にアクセスできないわけでナイ。
自分自身のロックフラグを持っていないスレッドが synchronized ブロック内を実行できないだけ。
[list]や[getSize]にはアクセス可能。
--------------------------------------------------
Q1 間違ってるのは?
a. public class Car
b. public abstract class Car
c. public class Car implements Vehicle
d. public synchronized Car extends AutoMobil
A1
d
synchronizedは、
synchronized メソッドかsynchronized ブロックしか使用不可
--------------------------------------------------
Q2 ThreadAがstaticAddObj()を実行してる間に、ThreadBがアクセスできるメソッドは?
01:import java.util.ArrayList;
02:public class Monitor {
03: public static ArrayList list = new ArrayList();
04:
05: public static synchronized void static AddObj(Object obj) {
06: list.add(obj);
07: }
08:
09: public static synchronized void staticRemoveObj(int i) {
10: if (i < list.size()) {
11: list.remove(i);
12: }
13: }
14:
15: public synchronized void addObj(Object obj) {
16: list.add(obj);
17: }
18:
19: public synchronized void removeObj(int i) {
20: if (0 < list.size()) {
21: list.remove(i);
22: }
23: }
24:
25: public int getSize() {
26: list.size();
27: }
28:}
a. staticAddObj(Object obj)
b. staticRemoveObj(int i)
c. addObj(Object obj)
d. removeObj(int i)
e. getSize()
A2
×a. staticAddObj(Object obj)
×b. staticRemoveObj(int i)
○c. addObj(Object obj)
○d. removeObj(int i)
○e. getSize()
staticなsynchronizedメソッドは、他のstaticなsynchronizedメソッドとシンクロする。
非staticなsynchronizedメソッドは、他の非staticなsynchronizedメソッドとシンクロする。
→staticはstatic同士で、非staticは非static同士でシンクロする。
--------------------------------------------------
Q3 正しいのは?
1: public class Monitor {
2: private int num1;
3: private int num2;
4: void increase(){
5: num1 ++;
6: num2 ++;
7: System.out.println(num1 == num2);
8: }
9: }
10:
11: public class ThreadClass extends Thread {
12: private Monitor m;
13: public ThreadClass(Monitor m) {
14: this.m = m;
15: }
16: public void run() {
17: for (int i = 0; i < 1000; i++) {
18: m.increase();
19: }
20: }
21: }
22:
23: public class MainClass {
24: public static void main(String args[]){
25: Monitor m = new Monitor();
26: ThreadClass th1 = new ThreadClass(m);
27: ThreadClass th2 = new ThreadClass(m);
28: th1.start();
29: th2.start();
30: }
31: }
a. trueまたはfalseを表示することがある
b. 常にtrueを表示する
c. 常にfalseを表示する
d. 例外が発生する
A3
a
プログラムが実行されると二つのスレッドが
同一のMonitorクラスのオブジェクトmのincrease()メソッドを呼ぶ。
片方のスレッドがincrease()実行中にもう片方のスレッドがincrease()を実行すると、num1とnum2の値は等しくなくなるタイミングが出る。
--------------------------------------------------
Q4 必ずtrueと出力させるためには?
public class Monitor {
private int num1;
private int num2;
void increase() {
num1 ++;
num2 ++;
System.out.println(num1 == num2);
}
}
public classThreadClass extends Thread {
private Monitor m;
public ThreadClass(Monitor m) {
this.m = m;
}
public void run() {
for (int i=0; i<1000; i++) {
m.increase();
}
}
}
public class MainClass {
public static void main(String[] args) {
Monitor m = new Monitor();
ThreadClass th1 = new ThreadClass(m);
ThreadClass th2 = new ThreadClass(m);
th1.start();
th2.start();
}
}
a.Monitorクラスを変更
public class Monitor {
private int num1;
private int num2;
void synchronized increase() {
num1 ++; num2++;
syso(num1 == num2);
}
}
b.Monitorクラスを変更
public class Monitor {
private int num1;
private int num2;
void increase() {
synchronized(this) {
num1 ++; num2++;
syso(num1 == num2);
}
}
}
c.ThreadClassを変更
public class ThreadClass extends Thread {
private Monitor m;
public ThreadClass(Monitor m) {
this.m = m;
}
public void synchronized run() {
for (int i = 0; i < 1000; i++) {
m.increase();
}
}
}
c.ThreadClassを変更
public class ThreadClass extends Thread {
private Monitor m;
public ThreadClass(Monitor m) {
this.m = m;
}
public void run() {
synchronized(this) {
for (int i = 0; i < 1000; i++) {
m.increase();
}
}
}
}
A4
b
--------------------------------------------------
Q5 deposit()が実行中だとして 正しいのは?
public class Monitor {
private int account;
public synchronized void deposit(int money) {
account = account - money;
}
public synchronized void withdraw(int money) {
account = account + money;
}
public int getAccount() {
return account;
}
}
a. 他のスレッドはこのオブジェクトのどのメソッドも実行できない。
b. 他のスレッドはwithdraw()メソッドのみ実行できる。
c. 他のスレッドはgetAccount()メソッドのみ実行できる。
d. 他のスレッドは全メソッドを実行できる。
A5
c
--------------------------------------------------
Q6 正しいのは?
import java.util.ArrayList;
public class Monitor {
private static ArrayList list = new ArrayList();
private Object lockObj1 = new Object();
private Object lockObj2 = new Object();
public void addObj1(Object obj) {
synchronized(lockObj1) {
list.add(obj);
}
}
public void removeObj1(int i) {
synchronized(lockObj1) {
if (i < list.size()) {
list.remove(i);
}
}
}
public void removeObj2(int i) {
synchronized(lockObj2) {
if(i < list.size()) {
list.remove(i);
}
}
}
}
a. コンパイルエラー。
b. addObj1のlist.add(obj)で例外が出うる。
c. removeObj1のlist.remove(i)で例外が出うる。
d. removeObj2のlist.remove(i)で例外が出うる。
e. 例外なし。
A6
c, d
同じlistを扱うのに異なるロックオブジェクトを使っているため
同時に複数スレッドからlistを変更してしまいうる。
で、IndexOutOgBoundsExceptionが出うる。
goto [J2SE1.4] INDEX
・synchronizedメソッドを使った排他制御
・synchronizedブロックを使った排他制御
[synchronizedメソッドを使った排他制御]
アクセス修飾子+synchronized+戻り値+メソッド名(引数リスト){...}
synchronizedメソッドには
非staticなものとstaticなもの
がある
・非staticなsynchronizedメソッド
synchronizedメソッドにあるスレッドにアクセスすると、
他のスレッドはこのメソッドにはアクセス出来なくなる。
→先にアクセスしたスレッドの処理が終わるまで待つ。
import java.util.ArrayList;
public class Monitor {
private ArrayList list = new ArrayList();
public synchronized void addObj(Object obj) {
list.add(obj);
}
}
Thread1がaddObjを実行中の間、
Thread2はaddObjにアクセス出来ない。
複数スレッドからアクセスされるオブジェクトを
スレッドプログラミングで[モニタ]という。
import java.util.ArrayList;
public class Monitor {
private ArrayList list = new ArrayList();
public synchronized void addObj(Object obj) {
list.add(obj);
}
public synchronized void removeObj(int idx) {
list.remove(idx);
}
public void getSize(int idx) {
list.size(idx);
}
}
Thread1がaddObjを実行中の間、
Thread2はremoveObjにもアクセス出来ない。
1つのsynchronizedメソッドが実行されている場合、
そのクラスに存在する全てのsynchronizedメソッドにロックがかかる。
クラス内の全てのsynchronizedメソッドは、シンクロし合って1セットとなる。
ただし、
synchronizedキーワードがついていない部分は排他制御の対象外
Thread1がaddObjを実行中の間も、
Thread2はgetSizeを実行できる。
要注意
フィールドlistを扱うメソッドaddObjとremoveObjにsynchronizedをつけても、
フィールドlist自体にロックがかかっていないので、
private以外のアクセス修飾子の、synchronizedでないメソッドでlistに意図せぬ変更をし得る。
・staticなsynchronizedメソッド
import java.util.ArrayList;
public class Monitor {
private static ArrayList list = new ArrayList();
public static synchronized void staticAddObj(Object obj) {
list.add(obj);
}
public static synchronized void staticRemoveObj(int i) {
if (i < list.size()) {
list.remove(i);
}
}
public synchronized void addObj(Object obj) {
list.add(obj);
}
public synchronized void removeObj(int i) {
if (i < list.size()) {
list.remove(i);
}
}
}
Thread1がstatidAddObjを実行中の間、
Thread2は
staticAddObjとstaticRemoveObjにはアクセス出来ないが、
addObjとremoveObjにはアクセス出来る。
Thread1がaddObjを実行中の間、
Thread2は
addObjとremoveObjにはアクセス出来ないが、
staticAddObjとstaticRemoveObjにはアクセス出来る。
非staticなsynchronizedメソッド同士
staticなsynchronizedメソッド同士
でシンクロする。
[synchronizedブロックを使った排他制御]
synchronizedメソッドでの排他制御:
全てのメソッドが対象になり、1クラスに1種類の排他制御しか出来ない。
synchronizedブロックでの排他制御:
多彩な排他制御の範囲を指定でき、複雑な排他制御も出来る。
synchronizedブロックの記述方法
synchronized (OBJECT) { ...... }
※OBJECT:
ロック用オブジェクト
synchronizedブロックを実行する為の権利みたいなもの
ロック用オブジェクトはObjectインスタンスでもStringインスタンスでも何でも可。
01:import java.utilArrayList;
02:public class Minitor {
03: public static ArrayList list = new ArrayList();
04: private Object lockObj = new Object();
05: public void addObj(Object obj) {
06: synchronized(lockObj) {
07: list.add(obj);
08: }
09: }
10:}
6行目でロック(ロックフラグ)を取得したスレッドのみが
synchronizedブロックの処理を続行できる。
Thread1がsynchronizedブロックを処理している間、
Thread2はlockObjを取得出来ないのでsynchronizedブロックを処理できない。
メソッド全体を排他制御の対象とするよりも、
メソッドの一部分だけを排他制御の対象とした方が、
排他制御の範囲を最小限に出来るため、パフォーマンスも上がる。
synchronizedブロックで複数種類の排他制御の実装
import java.util.ArrayList;
public class Monitor {
public static ArrayList list1 = new ArrayList();
public static ArrayList list2 = new ArrayList();
private Object lockObj1 = new Object();
private Object lockObj2 = new Object();
public void addObj1(Object obj) {
synchronized(lockObj1) {
list.add(obj);
}
}
public void addObj2(Object obj) {
synchronized(lockObj2) {
list.add(obj);
}
}
public synchronized void removeObj1(int i){
synchronized(lockObj1){
if(i < list.size()){
list1.remove(i);
}
}
}
public synchronized void removeObj2(int i){
synchronized(lockObj2){
if(i < list.size()){
list1.remove(i);
}
}
}
}
lockObjectはなんでもよい
import java.util.ArrayList;
public class Monitor {
public static ArrayList list = new ArrayList();
public void addObj1(Object obj){
synchronized(this){
list.add(obj);
}
}
public int getSize(Object obj){
return list.size();
}
}
単にロックオブジェクトが[this]なだけ。
synchronizedブロック内を実行中の間は、
他のスレッドが自分自身にアクセスできないわけでナイ。
自分自身のロックフラグを持っていないスレッドが synchronized ブロック内を実行できないだけ。
[list]や[getSize]にはアクセス可能。
--------------------------------------------------
Q1 間違ってるのは?
a. public class Car
b. public abstract class Car
c. public class Car implements Vehicle
d. public synchronized Car extends AutoMobil
A1
d
synchronizedは、
synchronized メソッドかsynchronized ブロックしか使用不可
--------------------------------------------------
Q2 ThreadAがstaticAddObj()を実行してる間に、ThreadBがアクセスできるメソッドは?
01:import java.util.ArrayList;
02:public class Monitor {
03: public static ArrayList list = new ArrayList();
04:
05: public static synchronized void static AddObj(Object obj) {
06: list.add(obj);
07: }
08:
09: public static synchronized void staticRemoveObj(int i) {
10: if (i < list.size()) {
11: list.remove(i);
12: }
13: }
14:
15: public synchronized void addObj(Object obj) {
16: list.add(obj);
17: }
18:
19: public synchronized void removeObj(int i) {
20: if (0 < list.size()) {
21: list.remove(i);
22: }
23: }
24:
25: public int getSize() {
26: list.size();
27: }
28:}
a. staticAddObj(Object obj)
b. staticRemoveObj(int i)
c. addObj(Object obj)
d. removeObj(int i)
e. getSize()
A2
×a. staticAddObj(Object obj)
×b. staticRemoveObj(int i)
○c. addObj(Object obj)
○d. removeObj(int i)
○e. getSize()
staticなsynchronizedメソッドは、他のstaticなsynchronizedメソッドとシンクロする。
非staticなsynchronizedメソッドは、他の非staticなsynchronizedメソッドとシンクロする。
→staticはstatic同士で、非staticは非static同士でシンクロする。
--------------------------------------------------
Q3 正しいのは?
1: public class Monitor {
2: private int num1;
3: private int num2;
4: void increase(){
5: num1 ++;
6: num2 ++;
7: System.out.println(num1 == num2);
8: }
9: }
10:
11: public class ThreadClass extends Thread {
12: private Monitor m;
13: public ThreadClass(Monitor m) {
14: this.m = m;
15: }
16: public void run() {
17: for (int i = 0; i < 1000; i++) {
18: m.increase();
19: }
20: }
21: }
22:
23: public class MainClass {
24: public static void main(String args[]){
25: Monitor m = new Monitor();
26: ThreadClass th1 = new ThreadClass(m);
27: ThreadClass th2 = new ThreadClass(m);
28: th1.start();
29: th2.start();
30: }
31: }
a. trueまたはfalseを表示することがある
b. 常にtrueを表示する
c. 常にfalseを表示する
d. 例外が発生する
A3
a
プログラムが実行されると二つのスレッドが
同一のMonitorクラスのオブジェクトmのincrease()メソッドを呼ぶ。
片方のスレッドがincrease()実行中にもう片方のスレッドがincrease()を実行すると、num1とnum2の値は等しくなくなるタイミングが出る。
--------------------------------------------------
Q4 必ずtrueと出力させるためには?
public class Monitor {
private int num1;
private int num2;
void increase() {
num1 ++;
num2 ++;
System.out.println(num1 == num2);
}
}
public classThreadClass extends Thread {
private Monitor m;
public ThreadClass(Monitor m) {
this.m = m;
}
public void run() {
for (int i=0; i<1000; i++) {
m.increase();
}
}
}
public class MainClass {
public static void main(String[] args) {
Monitor m = new Monitor();
ThreadClass th1 = new ThreadClass(m);
ThreadClass th2 = new ThreadClass(m);
th1.start();
th2.start();
}
}
a.Monitorクラスを変更
public class Monitor {
private int num1;
private int num2;
void synchronized increase() {
num1 ++; num2++;
syso(num1 == num2);
}
}
b.Monitorクラスを変更
public class Monitor {
private int num1;
private int num2;
void increase() {
synchronized(this) {
num1 ++; num2++;
syso(num1 == num2);
}
}
}
c.ThreadClassを変更
public class ThreadClass extends Thread {
private Monitor m;
public ThreadClass(Monitor m) {
this.m = m;
}
public void synchronized run() {
for (int i = 0; i < 1000; i++) {
m.increase();
}
}
}
c.ThreadClassを変更
public class ThreadClass extends Thread {
private Monitor m;
public ThreadClass(Monitor m) {
this.m = m;
}
public void run() {
synchronized(this) {
for (int i = 0; i < 1000; i++) {
m.increase();
}
}
}
}
A4
b
--------------------------------------------------
Q5 deposit()が実行中だとして 正しいのは?
public class Monitor {
private int account;
public synchronized void deposit(int money) {
account = account - money;
}
public synchronized void withdraw(int money) {
account = account + money;
}
public int getAccount() {
return account;
}
}
a. 他のスレッドはこのオブジェクトのどのメソッドも実行できない。
b. 他のスレッドはwithdraw()メソッドのみ実行できる。
c. 他のスレッドはgetAccount()メソッドのみ実行できる。
d. 他のスレッドは全メソッドを実行できる。
A5
c
--------------------------------------------------
Q6 正しいのは?
import java.util.ArrayList;
public class Monitor {
private static ArrayList list = new ArrayList();
private Object lockObj1 = new Object();
private Object lockObj2 = new Object();
public void addObj1(Object obj) {
synchronized(lockObj1) {
list.add(obj);
}
}
public void removeObj1(int i) {
synchronized(lockObj1) {
if (i < list.size()) {
list.remove(i);
}
}
}
public void removeObj2(int i) {
synchronized(lockObj2) {
if(i < list.size()) {
list.remove(i);
}
}
}
}
a. コンパイルエラー。
b. addObj1のlist.add(obj)で例外が出うる。
c. removeObj1のlist.remove(i)で例外が出うる。
d. removeObj2のlist.remove(i)で例外が出うる。
e. 例外なし。
A6
c, d
同じlistを扱うのに異なるロックオブジェクトを使っているため
同時に複数スレッドからlistを変更してしまいうる。
で、IndexOutOgBoundsExceptionが出うる。
goto [J2SE1.4] INDEX
[J2SE1.4] スレッド
スレッド
ソフトウェア(プログラム)の実行単位
1つのプログラムは最低1つのスレッドが存在する
public class SingleThreadExample {
public static void main(String[] args) {
syso("working");
}
}
上記プログラムを実行するとmainメソッドの処理を行う1つのスレッドが起動する。
→スレッドを1つだけ起動させるプログラムを【シングルスレッド】のプログラムという。
シングルスレッドのプログラムに対して複数スレッドが動くプログラムを【マルチスレッド】のプログラムと言う。
マルチスレッドプログラムの作成方法
Javaでマルチスレッドのプログラムを作成するには、スレッド生成のクラスを作成する必要がある。
スレッドの生成クラスの作成方法2つ
・Threadクラスを継承する方法
・Runnableインタフェースを実装する方法
【Threadクラスを継承する方法】
Threadクラスのサブクラスを作成
run()メソッドをオーバーライド
スレッドで処理したい内容を記述
public class ExtendingThreadSample extends Thread {
public void run() {
//any operation
}
}
次に
ExtendingThreadSampleをインスタンス化
インスタンスのstart()メソッドを呼ぶ
ことでスレッドが起動する。
public class MainClass {
public static void main(String[] args) {
ExtendingThreadSample th = new ExtendingThreadSample();
th.start();
}
}
スレッドを起動させる為に呼ぶメソッドはrun()メソッドではなく、start()メソッドである。
start()メソッドを呼び出したタイミングですぐにスレッドが実行されるわけではなく、
スレッドスケジューラに登録されるだけで、いつ実行するかはスレッドスケジューラが決定権を持つ。
【Runnableインタフェースを実装する方法】
Runnableインタフェースを実装
Runnableの抽象メソッドrun()メソッドを定義
スレッドで処理したい内容を記述
public class ImplementingRunnableSample implements Runnable {
public void run() {
//any operation
}
}
起動・実行するには
ImplementingRunnableSampleをインスタンス化
インスタンスをコンストラクタ引数として Threadクラスをインスタンス化
Threadクラスのインスタンスのstart()メソッドを呼ぶ
public class MainClass {
public static void main(string[] args) {
ImplementingRunnableSample myThread = new ImplementingRunnableSample();
Thread th = new Thread(myThread);
th.start();
}
}
Runnableインタフェースを実装したクラスには、start()メソッドがない為、
スレッドスケジューラに登録できない。
→Threadクラスのインスタンスを作成し、start()を呼んで実行する。
--------------------------------------------------
Q1 間違ってるのは?
a. スレッドを生成するクラスを作成する場合、Threadクラスを継承すればよい。
b. スレッドの実行開始はrun()メソッドを呼び出すことで行う。
c. スレッドを生成するクラスを作る場合、Runnableインタフェースを実装すればよい。
d. スレッドの実行開始はstart()メソッドを呼んで行う。
A1
b
start():スレッドを実行開始するメソッド
run():スレッドの処理内容を記述するメソッド
--------------------------------------------------
Q2 正しいのは?
01:class ThreadSample extends Thread {
02: public void run() {
03: for (int i=0; i<5; i++) {
04: System.out.println("hoge");
05: }
06: }
07:}
08:public class MainSample {
09: public static void main(String[] args) {
10: ThreadSample th = new ThreadSample();
11: th.run();
12: }
13:}
a. 10行目でコンパイルエラー
b. 12行目でコンパイルエラー
c. 実行時にエラー
d. 問題なく実行される
A2
d
スレッドの実行開始には、run()でなく、start()を呼ぶ。
run()を呼んだ場合は、スレッドとして実行されず、
同スレッドでrun()が実行されるだけ。
--------------------------------------------------
Q3 正しいのは?
01:classThreadSample implements Runnable {
02: public void run() {
03: for (int i=0; i<5;i++) {
04: System.out.println("hoge");
05: }
06: }
07:}
08:public class MainSample {
09: public static void main(Strng[] args) {
10: ThreadSample th = new ThreadSample();
11: th.start();
12: }
13:}
a. 10行目でコンパイルエラー
b. 11行目でコンパイルエラー
c. 実行時にエラー
d. 問題なく実行される
A3
b
10行目では問題なくインスタンス化されるが
ThreadSampleクラスはThreadクラスのサブクラスでないので
start()は呼び出せない。
--------------------------------------------------
Q4 (A)に入るのは?
01:public class ThreadSample implements Runnable {
02: public void run() {
03: for (int i=0; i<5; i++) {
04: System.out.println("hoge");
05: }
06: }
07: public static void main(String[] args) {
08: (A)
09: }
10:}
a. new ThreadSample().start();
b. new Thread(new ThreadSample()).start();
c. new Thread(ThreadSample).start();
d. new Thread(new ThreadSample()).run();
A4
b
--------------------------------------------------
Q5 正しいのは?
01:public class ThreadSample extends Thread {
02: public void run() {
03: for (int i=0; i<5; i++) {
04: System.out.println("hoge");
05: }
06: }
07:}
08:public class MainSample {
09: public static void main(String[] args) {
10: ThreadSample th = new ThreadSample();
11: Thread t = new Thread(th);
12: t.start();
13: }
14:}
a. 10行目でコンパイルエラー
b. 11行目でコンパイルエラー
c. 実行時にエラー
d. 問題なく実行される
A5
d
--------------------------------------------------
Q6 Threadクラスのインスタンスメソッドは?
a. sleep(long msec);
b. start();
c. wait();
d. run();
e.notifyAll();
f. join();
A6
○a. sleep(long msec);
○b. start();
×c. wait();
○d. run();
×e.notifyAll();
○f. join();
Thread#run(): スレッドの処理内容の実行
Thread#start():スレッド自体の実行開始
Thread#join():他のスレッドの実行終了を待機
THread#sleep(long msec):スレッドの実行を一時停止(static method)
Object#wait():他のスレッドからnotify()かnotifyAll()メソッドで呼ばれるまで待機
Object#notifyAll():待機している全スレッドを実行再開
goto [J2SE1.4] INDEX
ソフトウェア(プログラム)の実行単位
1つのプログラムは最低1つのスレッドが存在する
public class SingleThreadExample {
public static void main(String[] args) {
syso("working");
}
}
上記プログラムを実行するとmainメソッドの処理を行う1つのスレッドが起動する。
→スレッドを1つだけ起動させるプログラムを【シングルスレッド】のプログラムという。
シングルスレッドのプログラムに対して複数スレッドが動くプログラムを【マルチスレッド】のプログラムと言う。
マルチスレッドプログラムの作成方法
Javaでマルチスレッドのプログラムを作成するには、スレッド生成のクラスを作成する必要がある。
スレッドの生成クラスの作成方法2つ
・Threadクラスを継承する方法
・Runnableインタフェースを実装する方法
【Threadクラスを継承する方法】
Threadクラスのサブクラスを作成
run()メソッドをオーバーライド
スレッドで処理したい内容を記述
public class ExtendingThreadSample extends Thread {
public void run() {
//any operation
}
}
次に
ExtendingThreadSampleをインスタンス化
インスタンスのstart()メソッドを呼ぶ
ことでスレッドが起動する。
public class MainClass {
public static void main(String[] args) {
ExtendingThreadSample th = new ExtendingThreadSample();
th.start();
}
}
スレッドを起動させる為に呼ぶメソッドはrun()メソッドではなく、start()メソッドである。
start()メソッドを呼び出したタイミングですぐにスレッドが実行されるわけではなく、
スレッドスケジューラに登録されるだけで、いつ実行するかはスレッドスケジューラが決定権を持つ。
【Runnableインタフェースを実装する方法】
Runnableインタフェースを実装
Runnableの抽象メソッドrun()メソッドを定義
スレッドで処理したい内容を記述
public class ImplementingRunnableSample implements Runnable {
public void run() {
//any operation
}
}
起動・実行するには
ImplementingRunnableSampleをインスタンス化
インスタンスをコンストラクタ引数として Threadクラスをインスタンス化
Threadクラスのインスタンスのstart()メソッドを呼ぶ
public class MainClass {
public static void main(string[] args) {
ImplementingRunnableSample myThread = new ImplementingRunnableSample();
Thread th = new Thread(myThread);
th.start();
}
}
Runnableインタフェースを実装したクラスには、start()メソッドがない為、
スレッドスケジューラに登録できない。
→Threadクラスのインスタンスを作成し、start()を呼んで実行する。
--------------------------------------------------
Q1 間違ってるのは?
a. スレッドを生成するクラスを作成する場合、Threadクラスを継承すればよい。
b. スレッドの実行開始はrun()メソッドを呼び出すことで行う。
c. スレッドを生成するクラスを作る場合、Runnableインタフェースを実装すればよい。
d. スレッドの実行開始はstart()メソッドを呼んで行う。
A1
b
start():スレッドを実行開始するメソッド
run():スレッドの処理内容を記述するメソッド
--------------------------------------------------
Q2 正しいのは?
01:class ThreadSample extends Thread {
02: public void run() {
03: for (int i=0; i<5; i++) {
04: System.out.println("hoge");
05: }
06: }
07:}
08:public class MainSample {
09: public static void main(String[] args) {
10: ThreadSample th = new ThreadSample();
11: th.run();
12: }
13:}
a. 10行目でコンパイルエラー
b. 12行目でコンパイルエラー
c. 実行時にエラー
d. 問題なく実行される
A2
d
スレッドの実行開始には、run()でなく、start()を呼ぶ。
run()を呼んだ場合は、スレッドとして実行されず、
同スレッドでrun()が実行されるだけ。
--------------------------------------------------
Q3 正しいのは?
01:classThreadSample implements Runnable {
02: public void run() {
03: for (int i=0; i<5;i++) {
04: System.out.println("hoge");
05: }
06: }
07:}
08:public class MainSample {
09: public static void main(Strng[] args) {
10: ThreadSample th = new ThreadSample();
11: th.start();
12: }
13:}
a. 10行目でコンパイルエラー
b. 11行目でコンパイルエラー
c. 実行時にエラー
d. 問題なく実行される
A3
b
10行目では問題なくインスタンス化されるが
ThreadSampleクラスはThreadクラスのサブクラスでないので
start()は呼び出せない。
--------------------------------------------------
Q4 (A)に入るのは?
01:public class ThreadSample implements Runnable {
02: public void run() {
03: for (int i=0; i<5; i++) {
04: System.out.println("hoge");
05: }
06: }
07: public static void main(String[] args) {
08: (A)
09: }
10:}
a. new ThreadSample().start();
b. new Thread(new ThreadSample()).start();
c. new Thread(ThreadSample).start();
d. new Thread(new ThreadSample()).run();
A4
b
--------------------------------------------------
Q5 正しいのは?
01:public class ThreadSample extends Thread {
02: public void run() {
03: for (int i=0; i<5; i++) {
04: System.out.println("hoge");
05: }
06: }
07:}
08:public class MainSample {
09: public static void main(String[] args) {
10: ThreadSample th = new ThreadSample();
11: Thread t = new Thread(th);
12: t.start();
13: }
14:}
a. 10行目でコンパイルエラー
b. 11行目でコンパイルエラー
c. 実行時にエラー
d. 問題なく実行される
A5
d
--------------------------------------------------
Q6 Threadクラスのインスタンスメソッドは?
a. sleep(long msec);
b. start();
c. wait();
d. run();
e.notifyAll();
f. join();
A6
○a. sleep(long msec);
○b. start();
×c. wait();
○d. run();
×e.notifyAll();
○f. join();
Thread#run(): スレッドの処理内容の実行
Thread#start():スレッド自体の実行開始
Thread#join():他のスレッドの実行終了を待機
THread#sleep(long msec):スレッドの実行を一時停止(static method)
Object#wait():他のスレッドからnotify()かnotifyAll()メソッドで呼ばれるまで待機
Object#notifyAll():待機している全スレッドを実行再開
goto [J2SE1.4] INDEX
[J2SE1.4] 演算子とデータのメモリの割り当て
Q1 正しいのは?
a. int a = 0x30000;
b. byte b = -0200;
c. double c = 3E+100;
A1
整数リテラルの表現を問う問題
○a. int a = 0x30000;
頭の0xは、16進数を表す。16進数で30000は、10進数196608(=3*16^4)で、
intの表現可能範囲内。
○b. byte b = -0200;
頭の0は、8進数を表す。8進数で200は、10進数-128(=-2*8^2)で、
byteの表現可能範囲内。
○c. double c = 3E+100;
nE+yは、浮動小数表現のn*10^yを表す。3E+10は、10進数で30000000000で、
doubleの表現可能範囲内。
--------------------------------------------------
Q2 何が表示される?
01:public class JavaBasic [
02:
03: public static void main(String[] args) {
04: int b = 10;
05: b = ~b;
06: b = b >> 3;
07: b = b << 3;
08: syso(b);
09: }
10:}
11:
A2
-16
L.4: 10を2進数で表現すると[00000000000000000000000000001010](intは32bitなので32桁)になる。
L.5: ビット反転(~)すると[11111111111111111111111111110101]になる。
L.6: 3つ符号保存右シフト(>>)すると[11111111111111111111111111111110]となる。
符号保存右シフトは、最上位ビットが1のときは1が、0の時は0がシフトさせた後の最上に現れる。
符号無視右シフト(>>>)は常に0が現れる。
L.7: 左にシフト(<<)すると[11111111111111111111111111110000]となる。
これを10進数に直すと[-16]になる。
--------------------------------------------------
Q3 何が表示される?
public class JavaBasic {
public static void main(String[] args[]) {
int b = 10^10 + 10|10;
syso(b);
}
}
A3
30
ビット演算子は、優先順位が低い演算子で、[+]演算子の方が先に演算される。
→[10^(10 + 10)|10]となる。
前半部分[10^20]は、2進数で、
00000000000000000000000000001010 ^
00000000000000000000000000010100 =
00000000000000000000000000011110
という演算になる。
[^]演算子は、各ビット値を比較して異なる場合のみ1にする演算を行う。
後半部分は、
00000000000000000000000000011110 |
00000000000000000000000000001010 =
00000000000000000000000000011110
という演算になる。
[|]演算子は、各ビット値を比較してどちらか一方でも1の場合に1にする演算をする。
これを10進数に直すと、[30]になる。
--------------------------------------------------
Q4 実行結果は?
public class JavaBasic {
public static void main(String[] args) {
String a = null;
int b = null;
boolean c = (b > 5) | a.equals("ABC");
syso(c);
}
}
a. true
b. false
c. nullPointerException
A4
○c. nullPointerException
[|]演算子は、boolean型に対しても演算出来る。
論理演算子[||]と同じ演算結果になるが、[||]演算子の場合は、
左辺がtrueであれば右辺はtrueでもfalseでも演算結果はtrueになるため、
左辺がtrueの時は、右辺を実行しない。
論理演算子[|]は、左辺の結果が何であれ、必ず右辺を実行する。
a.equals("ABC")が実行されると、aがnullでヌルポが出る。
boolean c = (b > 5) || a.equals("ABC");
とすれば、実行結果trueとなる。
goto [J2SE1.4] INDEX
a. int a = 0x30000;
b. byte b = -0200;
c. double c = 3E+100;
A1
整数リテラルの表現を問う問題
○a. int a = 0x30000;
頭の0xは、16進数を表す。16進数で30000は、10進数196608(=3*16^4)で、
intの表現可能範囲内。
○b. byte b = -0200;
頭の0は、8進数を表す。8進数で200は、10進数-128(=-2*8^2)で、
byteの表現可能範囲内。
○c. double c = 3E+100;
nE+yは、浮動小数表現のn*10^yを表す。3E+10は、10進数で30000000000で、
doubleの表現可能範囲内。
--------------------------------------------------
Q2 何が表示される?
01:public class JavaBasic [
02:
03: public static void main(String[] args) {
04: int b = 10;
05: b = ~b;
06: b = b >> 3;
07: b = b << 3;
08: syso(b);
09: }
10:}
11:
A2
-16
L.4: 10を2進数で表現すると[00000000000000000000000000001010](intは32bitなので32桁)になる。
L.5: ビット反転(~)すると[11111111111111111111111111110101]になる。
L.6: 3つ符号保存右シフト(>>)すると[11111111111111111111111111111110]となる。
符号保存右シフトは、最上位ビットが1のときは1が、0の時は0がシフトさせた後の最上に現れる。
符号無視右シフト(>>>)は常に0が現れる。
L.7: 左にシフト(<<)すると[11111111111111111111111111110000]となる。
これを10進数に直すと[-16]になる。
--------------------------------------------------
Q3 何が表示される?
public class JavaBasic {
public static void main(String[] args[]) {
int b = 10^10 + 10|10;
syso(b);
}
}
A3
30
ビット演算子は、優先順位が低い演算子で、[+]演算子の方が先に演算される。
→[10^(10 + 10)|10]となる。
前半部分[10^20]は、2進数で、
00000000000000000000000000001010 ^
00000000000000000000000000010100 =
00000000000000000000000000011110
という演算になる。
[^]演算子は、各ビット値を比較して異なる場合のみ1にする演算を行う。
後半部分は、
00000000000000000000000000011110 |
00000000000000000000000000001010 =
00000000000000000000000000011110
という演算になる。
[|]演算子は、各ビット値を比較してどちらか一方でも1の場合に1にする演算をする。
これを10進数に直すと、[30]になる。
--------------------------------------------------
Q4 実行結果は?
public class JavaBasic {
public static void main(String[] args) {
String a = null;
int b = null;
boolean c = (b > 5) | a.equals("ABC");
syso(c);
}
}
a. true
b. false
c. nullPointerException
A4
○c. nullPointerException
[|]演算子は、boolean型に対しても演算出来る。
論理演算子[||]と同じ演算結果になるが、[||]演算子の場合は、
左辺がtrueであれば右辺はtrueでもfalseでも演算結果はtrueになるため、
左辺がtrueの時は、右辺を実行しない。
論理演算子[|]は、左辺の結果が何であれ、必ず右辺を実行する。
a.equals("ABC")が実行されると、aがnullでヌルポが出る。
boolean c = (b > 5) || a.equals("ABC");
とすれば、実行結果trueとなる。
goto [J2SE1.4] INDEX
[J2SE1.4] Java言語の基礎
Q1 コンパイルしたらどうなる?
01:package javabasic;
02:
03:public class JavaBasic1 {
04:
05: private void func() {
06: System.out.println("SJC-P!");
07: }
08:
09: public static void main(String[] args) {
10: JavaBasic1 a = new JavaBasic1();
11: a.func();
12: }
13:}
a. L3でエラー
b. L5でエラー
c. L10でエラー
d. L11でエラー
e. エラーなし
A1
e
まず、
L.10でmain()メソッドから、自分自身のオブジェクトを作れるのか。
→自分自身のクラスに含まれるメソッドから、自分自身のオブジェクトを作ることは出来る。
次に、
L.11でprivateなインスタンスメソッドfunc()を呼び出せるのか。
→インスタンスメソッドは オブジェクトに対して呼び出しを行うことと、
アクセス修飾子privateは 自分自身のクラスの中からはアクセスできること
ことから問題なし。
よって、
コンパイル出来る。
--------------------------------------------------
Q2 コンパイルしたらどなる?
01:package javabasic;
02:
03:interface JavaBasicIF {
04: String name = "hogehoge";
05: public void func1();
06: int func2();
07: public abstract String func3();
08:}
09:
10:public class JavaBasicImpl implements JavaBasicIF {
11: public void func1() {
12: syso("func1");
13: }
14:
15: int func2() {
16: syso("func2");
17: return 0;
18: }
19:
20: public String func3() {
21: syso("func3");
22: return name;
23: }
24:}
a. L4でエラー
b. L11でエラー
c. L15でエラー
d. L20でエラー
e. エラーなし
A2
c
インタフェースは、定数と抽象メソッドしか定義できない。
各メンバのシグニチャは、変数であればpublic final staticが、メソッドであればpublic abstractが自動付加される。
実装クラスは、インタフェースで定義された抽象メソッドと同じシグニチャのメソッドを定義する必要がある。
L6で定義されているのはpublic abstractなので、L15もpublicでなくてはならない。
--------------------------------------------------
Q3 正しいのは?
a. byteは、-127から128までの数値を扱える。
b. unsigned byteは、0から255までの数値を扱える。
c. intの最大値は、Integer.MAX_VALUEで得られる。
d. byte a = 10; byte b = 20; byte c = a + b;は文法的に正しい。
e. char c = 5000;は文法的に正しい。
A3
×a.
byteで扱えるのは、-128〜127までの数値。
×b.
javaに、unsignedなんてない。
○c.
各基本データ型に対応するラッパクラスの
MAX_VALUE、MIN_VALUE static変数で、最大、最小値を得られる。
×d.
整数型は演算の際全てintにキャストされてから計算される。
byte c = a + b;の右辺の演算結果はintになるため、コンパイルエラーになる。
○e.
charは、2バイトの符号なし整数(0〜65535)を扱える。
--------------------------------------------------
Q4
a. strictfpは変数やメソッドの前に指定するJavaの修飾子である。
b. transientは、オブジェクトをシリアライズする際に、シリアライズ対象のフィールドにつける修飾子である。
c. volatileは、コンパイラに指示を与えるための修飾子である。
d. gotoを使ってラベルをつけた行へジャンプできる。
A4
×a.
strictfpは、classやinterfaceの前につける修飾子。
修飾子 strictfp を付与しクラスやメソッドを宣言した場合、
そのスコープ内の式は全て FP-strict となる。
FP-strict の式内では、計算の中間結果の表現もすべて
IEEE 754 規格に定められた数値集合が使用される。
逆に strictfp で宣言されていないクラスやメソッド内の式では、
中間結果の表現に指数拡張範囲を用いる裁量が実装に対して許されている。
つまりプラットフォームによって IEEE 754 規格外の数値集合が
使われる可能性があり、式内の浮動小数点数の動作が変わる可能性があるということ。
×b.
transientは、オブジェクトをシリアライズする際に、
シリアライズ対象外のフィールドにつける修飾子。
○c.
volatileは、コンパイラがフィールドに対して行う最適化を行わないように指示する修飾子。
×d.
javaでは、gotoは意味の無い予約語。
goto [J2SE1.4] INDEX
01:package javabasic;
02:
03:public class JavaBasic1 {
04:
05: private void func() {
06: System.out.println("SJC-P!");
07: }
08:
09: public static void main(String[] args) {
10: JavaBasic1 a = new JavaBasic1();
11: a.func();
12: }
13:}
a. L3でエラー
b. L5でエラー
c. L10でエラー
d. L11でエラー
e. エラーなし
A1
e
まず、
L.10でmain()メソッドから、自分自身のオブジェクトを作れるのか。
→自分自身のクラスに含まれるメソッドから、自分自身のオブジェクトを作ることは出来る。
次に、
L.11でprivateなインスタンスメソッドfunc()を呼び出せるのか。
→インスタンスメソッドは オブジェクトに対して呼び出しを行うことと、
アクセス修飾子privateは 自分自身のクラスの中からはアクセスできること
ことから問題なし。
よって、
コンパイル出来る。
--------------------------------------------------
Q2 コンパイルしたらどなる?
01:package javabasic;
02:
03:interface JavaBasicIF {
04: String name = "hogehoge";
05: public void func1();
06: int func2();
07: public abstract String func3();
08:}
09:
10:public class JavaBasicImpl implements JavaBasicIF {
11: public void func1() {
12: syso("func1");
13: }
14:
15: int func2() {
16: syso("func2");
17: return 0;
18: }
19:
20: public String func3() {
21: syso("func3");
22: return name;
23: }
24:}
a. L4でエラー
b. L11でエラー
c. L15でエラー
d. L20でエラー
e. エラーなし
A2
c
インタフェースは、定数と抽象メソッドしか定義できない。
各メンバのシグニチャは、変数であればpublic final staticが、メソッドであればpublic abstractが自動付加される。
実装クラスは、インタフェースで定義された抽象メソッドと同じシグニチャのメソッドを定義する必要がある。
L6で定義されているのはpublic abstractなので、L15もpublicでなくてはならない。
--------------------------------------------------
Q3 正しいのは?
a. byteは、-127から128までの数値を扱える。
b. unsigned byteは、0から255までの数値を扱える。
c. intの最大値は、Integer.MAX_VALUEで得られる。
d. byte a = 10; byte b = 20; byte c = a + b;は文法的に正しい。
e. char c = 5000;は文法的に正しい。
A3
×a.
byteで扱えるのは、-128〜127までの数値。
×b.
javaに、unsignedなんてない。
○c.
各基本データ型に対応するラッパクラスの
MAX_VALUE、MIN_VALUE static変数で、最大、最小値を得られる。
×d.
整数型は演算の際全てintにキャストされてから計算される。
byte c = a + b;の右辺の演算結果はintになるため、コンパイルエラーになる。
○e.
charは、2バイトの符号なし整数(0〜65535)を扱える。
--------------------------------------------------
Q4
a. strictfpは変数やメソッドの前に指定するJavaの修飾子である。
b. transientは、オブジェクトをシリアライズする際に、シリアライズ対象のフィールドにつける修飾子である。
c. volatileは、コンパイラに指示を与えるための修飾子である。
d. gotoを使ってラベルをつけた行へジャンプできる。
A4
×a.
strictfpは、classやinterfaceの前につける修飾子。
修飾子 strictfp を付与しクラスやメソッドを宣言した場合、
そのスコープ内の式は全て FP-strict となる。
FP-strict の式内では、計算の中間結果の表現もすべて
IEEE 754 規格に定められた数値集合が使用される。
逆に strictfp で宣言されていないクラスやメソッド内の式では、
中間結果の表現に指数拡張範囲を用いる裁量が実装に対して許されている。
つまりプラットフォームによって IEEE 754 規格外の数値集合が
使われる可能性があり、式内の浮動小数点数の動作が変わる可能性があるということ。
×b.
transientは、オブジェクトをシリアライズする際に、
シリアライズ対象外のフィールドにつける修飾子。
○c.
volatileは、コンパイラがフィールドに対して行う最適化を行わないように指示する修飾子。
×d.
javaでは、gotoは意味の無い予約語。
goto [J2SE1.4] INDEX
