【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 は代入できない
obj は TypeA 型の変数 として扱われているため、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 メソッドの引数 msg は main の変数 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