本記事の目次
模擬問題に挑戦!
では、今回解説したことの理解度を確認するため、4問の模擬問題に挑戦してみましょう。
問題1
次のコードがあります。コンパイルエラーとなる行は次のどれですか。3つ選択してください。
class Sample4 { static void methodA() { methodB(); Test.methodB(); methodC(); Test.methodD(); } static void methodB() { } void methodC() { methodB(); Test.methodB(); methodD(); Test.methodD(); } void methodD() { } }
- A. 3行目
- B. 4行目
- C. 5行目
- D. 6行目
- E. 10行目
- F. 11行目
- G. 12行目
- H. 13行目
解答・解説
「クラス名.メソッド名
」という呼び出しは、staticメソッドでは許可されていますが、インスタンスメンバでは許可されていません。また、各行の説明は以下のとおりです。
- 3行目:(OK)staticメソッド → staticメソッド
- 4行目:(OK)staticメソッド → staticメソッド(クラス名での呼び出し)
- 5行目:(NG)staticメソッド → インスタンスメソッド
- 6行目:(NG)staticメソッド → インスタンスメソッド(クラス名での呼び出し)
- 10行目:(OK)インスタンスメソッド → staticメソッド
- 11行目:(OK)インスタンスメソッド → staticメソッド(クラス名での呼び出し)
- 12行目:(OK)インスタンスメソッド → インスタンスメソッド
- 13行目:(NG)インスタンスメソッド → インスタンスメソッド(クラス名での呼び出し)
したがって、5行目(C)、6行目(D)、13行目(H)はコンパイルエラーとなります。
〔正解:C、D、H〕
問題2
以下のコードを、コンパイル、実行した場合、正しい解答はどれですか?
class Sample5 { static int x = 1; int y = 1; public static void main(String[] args) { Sample5 obj1 = new Sample5(); Sample5 obj2 = new Sample5(); obj1.x = 5; obj1.y = 6; obj2.x = 7; obj2.y = 8; System.out.println("ans:" + obj1.x + obj1.y + obj2.x + obj2.y); } }
- A. ans:5678
- B. ans:5656
- C. ans:7878
- D. ans:7676
- E. ans:7678
解答・解説
5~6行目で、Sample5
クラスのインスタンスを作成しています。Sample5
クラスには、static変数としてx
変数、インスタンス変数としてy
変数が宣言されています。インスタンス変数はインスタンスごとに領域を取りますが、static変数は1箇所しか領域を取りません。static変数であるx
変数に、7行目で5
を代入した後、9行目で7
を再代入していることから、実行結果は選択肢Eになります。
〔正解:E〕
問題3
以下のコードを、コンパイル、実行した場合、正しい解答はどれですか?
public class Sample6{ static final Sample6 obj = new Sample6(); public static void main(String[] args) { Sample6 one = obj; Sample6 two = obj.foo(obj); Sample6 three = obj; System.out.println((one == two) + " " + (one == three)); } Sample6 foo(Sample6 c) { c = new Sample6(); return c; } }
- A. 2行目でコンパイルエラーが発生する
- B. 10行目でコンパイルエラーが発生する
- C. true true
- D. false true
- E. false false
- F. true false
- G. 実行時エラー
解答・解説
staticと参照情報のコピーを絡めた問題です。
-
2行目:staticな定数として
obj
が宣言されています。 -
4行目:
one
変数にその参照情報が代入されるため、obj
とone
は同じインスタンスを参照します。 -
5行目:
foo()
メソッドの戻り値(つまり新しいインスタンス)が代入されます。 -
6行目:
obj
変数が参照しているインスタンスをthree
変数が参照すると定義しています。
つまり、obj
、one
、three
の各変数は同じインスタンスを参照しています。したがって、実行結果は選択肢Dとなります。staticは、このように独自クラス型で宣言した参照変数にも付与が可能です。
また、参照情報コピーの詳細については、本連載の1回目を参照してください。
〔正解:D〕
問題4
次のコードがあります。①に挿入するコードでコンパイルエラーとなるものはどれですか。2つ選択してください。
class Foo { static String data = "Java"; static void method() { System.out.println("data : " + data); } } public class Sample7 extends Foo{ public static void main(String[] args) { [ ① ] } }
- A. method();
- B. Foo.method();
- C. this.method();
- D. super.method();
- E. new Foo().method();
Sample7
クラスはFoo
クラスのサブクラスです。したがって、選択肢Aのmethod()
メソッド呼び出しは、自クラス内のstaticメソッド呼び出しと同様であるため問題ありません。また、クラス名での呼び出し(選択肢B)、明示的にインスタンス化しての呼び出し(選択肢E)も問題ありません。
一方、staticメンバからthis
(選択肢C)やsuper
(選択肢D)を参照することはできません。this
は自インスタンスを、super
は自インスタンスから見た親インスタンスを参照するからです。本文でstaticメンバからインスタンスメンバに直接アクセスすることはできないと説明しましたが、それと同じ理由です。
〔正解:C、D〕