🐥

【Java SE 17 Silver】自分が間違えた基本データ型と文字列の操作の問題3選(問題+解説付き)1

に公開

はじめに

今年中に Java SE 17 Silver の資格取得を目標に、本格的に学習を始めました。
勉強の中で、特に理解が深まった問題や「つまずきやすいポイントだな」と感じた箇所をいくつかピックアップし、この記事でまとめて解説していこうと思います。

基本データ型と文字列の操作の問題

次のコードをコンパイル、実行したときの結果として正しいものを選びなさい。(1つ選択)

問題1

class Parent {
    public void run() {
        System.out.println("Parent");
    }
}

class TypeA extends Parent {
    @Override
    public void run() {
        System.out.println("A");
    }
}

class TypeB extends Parent {
    @Override
    public void run() {
        System.out.println("B");
    }
}

public class Demo {
    public static void main(String[] args) {
        var obj = new TypeA();  
        obj = new TypeB();  
        obj.run();
    }
}

選択肢

  • A. コンパイルエラーになる
  • B. 実行時エラーになる
  • C.「Parent」と表示される
  • D.「A」と表示される
  • E.「B」と表示される

正解は、


正解:A. コンパイルエラーになる

解説

1. var は「最初の代入で型が確定する」

var obj = new TypeA();

この時点で obj の静的型は TypeA に決定されます。
var型推論 の仕組みであり、右辺の型をそのまま採用します。

つまり、次のコードと同じ扱いです。

TypeA obj = new TypeA();

2. TypeA と TypeB は互いに代入互換性がない

両方とも Parent を継承していますが、TypeA と TypeB の間には継承関係がありません

TypeA extends Parent
TypeB extends Parent

兄弟クラス同士の関係になるため、互いに代入はできません。

3. そのため次の行でコンパイルエラーになる

obj = new TypeB();  // ❌ TypeA 変数に TypeB は代入できない

objTypeA 型の変数 として扱われているため、TypeB のインスタンスは代入できません。
この行が原因でコンパイルエラーとなります。

✅ 補足:コンパイルを通したい場合

親クラス型で変数を宣言すれば、両方の型を扱えます。

Parent obj = new TypeA();
obj = new TypeB();  // ✅ OK

問題2

次のコードをコンパイル、実行したときの結果として正しいものを選びなさい。(1つ選択)

public class Example {
    public static void main(String[] args) {
        String text = "apple world";
        changeText(text);
        System.out.println(text);
    }

    private static void changeText(String msg) {
        msg.replaceAll("apple", "orange");
    }
}

選択肢

  • A. apple world と表示される
  • B. orange world と表示される
  • C. world と表示される
  • D. orange と表示されれる
  • E. コンパイルエラーが発生する
  • F. 実行時例外がスローされる

正解は、

正解:A. apple world と表示される

解説

1. String は「不変(immutable)」である

Java の String は不変のオブジェクトとして設計されています。
そのため、次のメソッドを呼び出したとしても、

msg.replaceAll("apple", "orange");

この処理は 書き換え後の新しい文字列を返すだけで、msg
そのものは変更されません。

2. changeText 内の変更は main の text に影響しない

changeText メソッドの引数 msgmain の変数 text
とは別のローカル変数
です。
さらに String
は不変であるため、置換結果を変数に再代入しない限り、値は更新されません。

3. 出力される内容

main の System.out.println(text); が参照するのは
変更前の "apple world" のままです。

問題3

次のコードをコンパイル、実行したときの結果として正しいものを選びなさい。(1つ選択)

public class DemoBuilder {
    public static void main(String[] args) {
        StringBuilder builder = new StringBuilder("xyz123");
        System.out.println(builder.capacity());
    }
}

選択肢

  • A. 6 が表示される
  • B. 16 が表示される
  • C. 17 が表示される
  • D. 22 が表示される

正解は、

正解:D. 22 が表示される

解説

1. StringBuilder の capacity とは

StringBuilder が内部で保持している 拡張可能なバッファ領域の大きさ
を指します。
これは文字列の長さ(length)とは無関係であり、あらかじめ余裕を持って確保されています。


2. StringBuilder(String) コンストラクタの仕様

文字列を渡して生成した場合、初期容量は次の計算式で決定されます。

初期容量 = 文字列の長さ + 16

3. 今回のケースに当てはめると

StringBuilder builder = new StringBuilder("xyz123");
  • "xyz123" の長さ → 6\
  • 容量計算 → 6 + 16 = 22

したがって、

System.out.println(builder.capacity());

の結果は 22 となります。

Discussion