Javaの基本構文とデータ型

2025-08-01

はじめに

Javaは世界中で広く使用されているプログラミング言語で、その安定性と汎用性から企業システムやAndroidアプリ開発など様々な場面で活用されています。この記事では、Javaプログラミングを始めるにあたって必須となる「基本構文」と「データ型」について、詳細に解説します。

Javaの基本構文

Hello Worldプログラム

Javaの基本構文を理解するために、伝統的な「Hello World」プログラムから始めましょう。

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

このプログラムを分解して解説します。

  1. public class HelloWorld – クラス宣言。Javaではすべてのコードがクラス内に記述されます。
  2. public static void main(String[] args) – プログラムのエントリーポイント。実行時に最初に呼び出されるメソッドです。
  3. System.out.println() – コンソールに文字列を出力するメソッド。

Javaプログラムの構造

次の例は典型的なJavaプログラムの構造です。

// パッケージ宣言(オプション)
package com.example.myapp;

// インポート文(必要なライブラリをインポート)
import java.util.Scanner;

// クラス定義
public class MyClass {

    // メインメソッド
    public static void main(String[] args) {
        // プログラムの処理をここに記述
    }

    // 他のメソッド
    public void myMethod() {
        // メソッドの処理
    }
}

最初にパッケージ宣言とインポート文があり、必要なライブラリを読み込みます。public class MyClass でクラスを定義し、その中にプログラムの実行開始点である main メソッドを持ちます。main メソッドには、実際の処理内容を記述します。また、myMethod のように別のメソッドを追加して、プログラムを整理・拡張することもできます。Javaの基本的な構造とクラス設計の枠組みを理解するための基本例です。

コメントの書き方

Javaには3種類のコメントがあります。

  1. 単一行コメント: // コメント内容
  2. 複数行コメント: /* */
   /* コメント内容
      複数行にわたる場合 */
  1. ドキュメンテーションコメント: /** **/
   /**
    * ドキュメンテーションコメント
    * クラスやメソッドの説明に使用
    */

Javaのデータ型(基本データ型と参照型)

Javaのデータ型は「プリミティブ型」と「参照型」の2つに大別されます。

プリミティブ型(基本データ型)

Javaのプリミティブ型は、プログラムの基本的なデータを効率よく扱うために重要な役割を持ちます。これらはオブジェクトではなく、メモリ上に直接値を保持するため、処理速度が速く、メモリ消費も少ないのが特徴です。intdoubleboolean など8種類が用意され、演算や比較を高速に行えます。特に数値処理や制御構文では頻繁に使われ、Javaの高いパフォーマンスを支える基盤的な仕組みとなっています。Javaには以下の8つのプリミティブ型があります。

データ型サイズ説明範囲
byte8ビット整数-128 ~ 127byte b = 100;
short16ビット整数-32,768 ~ 32,767short s = 10000;
int32ビット整数-2^31 ~ 2^31-1int i = 100000;
long64ビット整数-2^63 ~ 2^63-1long l = 100000L;
float32ビット単精度浮動小数点数約±3.4e+38Ffloat f = 3.14f;
double64ビット倍精度浮動小数点数約±1.8e+308double d = 3.141592;
char16ビットUnicode文字‘\u0000’ ~ ‘\uffff’char c = 'A';
boolean1ビット真偽値true/falseboolean flag = true;

参照型

プリミティブ型以外はすべて参照型です。Javaの参照型は、オブジェクトの実体ではなく、その場所(アドレス)を参照する仕組みを持つデータ型です。クラスや配列、インターフェース、文字列(String)などが該当し、柔軟で高度なデータ操作を可能にします。参照型はメモリ上のオブジェクトを指し示すため、複雑なデータ構造を扱う際に非常に重要です。また、プリミティブ型とは異なり、メソッドやプロパティを持ち、オブジェクト指向プログラミングの基盤として機能します。主な参照型には以下があります。

  1. String – 文字列を扱うクラス
   String name = "Javaプログラマー";
  1. 配列 – 同じ型の複数の値を格納
   int[] numbers = {1, 2, 3, 4, 5};
  1. クラス – ユーザー定義型
// ユーザー定義型「Person」
public class Person {
    // フィールド(データメンバ)
    private String name;
    private int age;

    // コンストラクタ(初期化)
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // メソッド(機能)
    public void greet() {
        System.out.println("こんにちは、私は " + name + " です。年齢は " + age + " 歳です。");
    }
}
  1. インターフェース – 抽象的な振る舞いを定義
public interface Animal {
    void speak(); // メソッドの定義(実装なし)
}

リテラル

リテラルとは、ソースコードに直接記述される値のことです。

  • 整数リテラル: 42, 0x2A (16進数), 052 (8進数), 0b101010 (2進数)
  • 浮動小数点数リテラル: 3.14, 6.02e23
  • 文字リテラル: 'A', '\n' (改行), '\u0041' (Unicode)
  • 文字列リテラル: "Hello"
  • 論理リテラル: true, false
  • nullリテラル: null

変数と定数

変数の宣言と初期化

Javaの変数の宣言と初期化は、他の言語(たとえば JavaScript や Python)と比較して、厳格な型指定と文法ルールがあるのが大きな特徴です。以下に注意点と他言語との違いをわかりやすく説明します。

int number = 10;         // 整数型
String name = "Tom";     // 文字列型(クラス)
boolean isActive = true; // 真偽値型

注意点①:型の指定が必須(静的型付け)

Javaでは、変数を宣言する際にデータ型を明示する必要があります。型が違えば代入できません。

int age = "20";  // エラー!文字列をint型に代入できない

注意点②:宣言だけでは使えない(初期化が必要)

int score;
// System.out.println(score); // コンパイルエラー:初期化されていない変数

Javaではローカル変数(メソッド内など)を初期化せずに使うとコンパイルエラーになります。
ただし、**フィールド変数(クラスの中で宣言された変数)**にはデフォルト値(0, null など)が自動で入ります。

注意点③:定数はfinalで宣言

final double PI = 3.14159;
// PI = 3.0; // エラー:final変数は再代入不可
特徴JavaJavaScriptPython
型の指定必須(静的型付け)不要(動的型付け)不要(動的型付け)
初期化なし使用ローカルでは不可OK(undefined)OK(NameErrorだが実行時)
定数finalで宣言constまたはObject.freeze命名規則(全大文字など)
変数の再宣言同じスコープ内では不可varでは可、letは不可同名で再代入は可

JavaScript の場合(柔軟)

let a = 10;
a = "hello"; // OK(動的に型が変わる)

Python の場合(柔軟)

x = 5
x = "world"  # OK(型の再代入可能)

Java の場合(厳格)

int a = 10;
a = "hello"; // エラー!型が違う
Javaの注意点他言語との差
変数には必ず型が必要(例: int, StringPythonやJSでは不要
初期化されていない変数は使えないJSはundefined, Pythonは実行時エラー
定数を使うときはfinalを使う必要Pythonには構文レベルの定数なし
同じ名前の変数は同一スコープで再宣言不可JSのvarなどでは再宣言できてしまう
データ型 変数名 [= 初期値];
int age;          // 宣言のみ
age = 25;         // 後で初期化
double price = 9.99;  // 宣言と初期化を同時に

定数の宣言

変更できない値を定義するにはfinalキーワードを使用します。

final double PI = 3.14159;
final int MAX_USERS = 100;

慣例として、定数名はすべて大文字でアンダースコアで単語を区切ります。

変数のスコープ

変数の有効範囲(スコープ)は、その変数が宣言されたブロック内に限定されます。次のコードは変数のスコープ(有効範囲)を示す例です。

public class ScopeExample {
    int instanceVar = 10;  // インスタンス変数(クラス全体で有効)

    public void myMethod() {
        int localVar = 20;  // ローカル変数(メソッド内でのみ有効)

        if (true) {
            int blockVar = 30;  // ブロック変数(if文内でのみ有効)
            System.out.println(blockVar);
        }
        // System.out.println(blockVar);  // エラー: blockVarは見えない
    }
}

instanceVar はクラス全体で利用できるインスタンス変数で、オブジェクトごとに保持されます。localVar はメソッド内だけで使えるローカル変数で、メソッドが終了すると消えます。blockVarif文内でのみ有効なブロック変数で、ブロックを抜けると参照できません。スコープを理解することで、変数の寿命やメモリ効率、意図しないアクセスを防ぐ安全なコード設計が可能になります。

演算子

Javaには様々な演算子があります。

算術演算子

演算子説明
+加算a + b
減算a - b
*乗算a * b
/除算a / b
%剰余a % b

代入演算子

演算子同等の式
=a = ba = b
+=a += ba = a + b
-=a -= ba = a - b
*=a *= ba = a * b
/=a /= ba = a / b
%=a %= ba = a % b

比較演算子

演算子説明
==等しいa == b
!=等しくないa != b
>より大きいa > b
<より小さいa < b
>=以上a >= b
<=以下a <= b

論理演算子

演算子説明
&&論理積(AND)a && b
||論理和(OR)a || b
!否定(NOT)!a

インクリメント/デクリメント演算子

演算子説明
++インクリメントa++ または ++a
デクリメントa-- または --a

配列

配列の宣言と初期化

Javaの配列は、同じデータ型の複数の値をまとめて扱うための仕組みです。まず、配列を使うには宣言初期化が必要です。宣言は「int[] numbers;」のように型と変数名を指定し、初期化は「numbers = new int[5];」のように要素数を指定してメモリを確保します。宣言と初期化を同時に行うこともでき、「int[] numbers = {10, 20, 30};」のように書けば、値を直接代入できます。このように配列を使うと、複数のデータを効率的に管理できます。

// 宣言方法1
データ型[] 配列名 = new データ型[要素数];

// 宣言方法2
データ型[] 配列名 = {値1, 値2, 値3, ...};

次のコードについて解説します。int[] numbers = new int[5]; では、5個の整数を格納できるint型配列を作成しています。配列の各要素にはインデックス(0から始まる番号)でアクセスし、numbers[0] = 10; のように値を代入します。一方、String[] names = {"Alice", "Bob", "Charlie"}; のように、初期化と同時に値を設定することもできます。配列は同じ型のデータをまとめて扱う際に便利で、繰り返し処理やデータ管理に広く利用されます。

int[] numbers = new int[5];  // 5要素のint配列
numbers[0] = 10;
numbers[1] = 20;
// ...

String[] names = {"Alice", "Bob", "Charlie"};  // 初期化と同時に代入

配列の操作

int[] nums = {10, 20, 30, 40, 50}; で整数の配列を初期化し、nums[0] のようにインデックスを使って要素にアクセスします。nums.length は配列の要素数を取得するプロパティで、ループ処理に利用されます。for文ではインデックスを使って順に処理を行い、for-each文(拡張for文)では要素を直接取り出して簡潔に繰り返し処理ができます。これにより、配列の内容を効率的に操作・出力できます。

int[] nums = {10, 20, 30, 40, 50};

// 要素へのアクセス
int first = nums[0];  // 10
nums[1] = 25;         // 20を25に変更

// 配列の長さ
int length = nums.length;  // 5

// 配列のループ処理
for (int i = 0; i < nums.length; i++) {
    System.out.println(nums[i]);
}

// 拡張for文(for-each)
for (int num : nums) {
    System.out.println(num);
}

文字列(String)操作

JavaのStringクラスは文字列を操作するための豊富なメソッドを提供しています。

基本的な文字列操作

Stringはオブジェクト型であり、文字列の扱いに多くの便利なメソッドが用意されています。+演算子で文字列を結合し、length()で文字数を取得できます。substring()を使うと一部の文字列を抜き出せます。equals()equalsIgnoreCase()は内容の比較に使用し、indexOf()contains()で文字列内の検索が可能です。また、split()で区切り文字ごとに分割し、replace()で一部の文字列を別の文字列に置き換えることもできます。これらを理解することで、テキスト処理を効率的に行うことができます。

String str1 = "Hello";
String str2 = "World";

// 文字列の結合
String combined = str1 + " " + str2;  // "Hello World"

// 文字列の長さ
int length = combined.length();  // 11

// 部分文字列の取得
String sub = combined.substring(6);  // "World"
String sub2 = combined.substring(0, 5);  // "Hello"

// 文字列の比較
boolean isEqual = str1.equals("Hello");  // true
boolean isEqualIgnoreCase = str1.equalsIgnoreCase("hello");  // true
int compareResult = str1.compareTo("Hello");  // 0 (等しい場合)

// 文字列の検索
int index = combined.indexOf("World");  // 6
boolean contains = combined.contains("lo W");  // true

// 文字列の分割
String[] parts = combined.split(" ");
// parts[0] = "Hello", parts[1] = "World"

// 文字列の置換
String replaced = combined.replace("World", "Java");  // "Hello Java"

StringBuilderクラス

大量の文字列操作が必要な場合、StringBuilderを使用すると効率的です。次のコードは、StringBuilderクラスを使って文字列を効率的に連結する方法を示しています。

StringBuilder sb = new StringBuilder();
sb.append("Hello");
sb.append(" ");
sb.append("World");
String result = sb.toString();  // "Hello World"

通常のStringの結合(+演算子)は新しい文字列オブジェクトを都度生成するため、繰り返し処理では非効率になります。一方、StringBuilderは可変の文字列バッファを持ち、append()メソッドで内容を追加しても新しいオブジェクトを作らないため、高速に処理できます。最後にtoString()メソッドで通常のString型に変換し、完成した文字列(この場合は "Hello World")を取得します。大量の文字列操作に向いた方法です。

型変換

自動型変換(拡大変換)

小さい型から大きい型への変換は自動的に行われます。

int i = 100;
long l = i;  // intからlongへ自動変換
double d = l;  // longからdoubleへ自動変換

int i = 100; で整数値を宣言し、それをlong l = i; と代入すると、自動的にintからlongへ変換されます。これは、longの方が広い範囲の値を扱えるためです。さらにdouble d = l; では、整数のlongが浮動小数点型のdoubleへ自動的に変換されます。このような変換は型の範囲が広い方向に限り、明示的なキャストを必要とせず安全に行われます。

明示的型変換(縮小変換)

大きい型から小さい型への変換にはキャストが必要です。

double d = 100.04;
long l = (long)d;  // 100に切り捨て
int i = (int)l;    // 100

double d = 100.04; で小数を持つ値を宣言し、(long)d とすることで double から long へ明示的に変換しています。この際、小数点以下は切り捨てられ、l には 100 が代入されます。続いて (int)l により long から int へ変換され、同じく 100 となります。このように、範囲が狭い型への変換では明示的なキャスト指定が必要であり、精度が失われる場合があるため注意が必要です。

文字列と数値の変換

次のコードは数値と文字列の変換を表しています。

// 文字列から数値へ
String numStr = "123";
int num = Integer.parseInt(numStr);
double d = Double.parseDouble("3.14");

// 数値から文字列へ
String s1 = Integer.toString(123);
String s2 = Double.toString(3.14);
String s3 = "" + 456;  // 簡易的な方法

Integer.parseInt()Double.parseDouble() は、文字列をそれぞれ intdouble に変換するメソッドです。逆に、数値を文字列に変換する場合は Integer.toString()Double.toString() を使います。また、"" + 数値 のように空文字を足す簡易的な方法でも文字列化できます。これらの変換は、ユーザー入力やファイル読み込みなど、文字列と数値をやり取りする場面でよく使われます。

よくあるエラーとデバッグ

コンパイルエラー

コンパイルエラーは、プログラムを実行する前の段階で、コンパイラによって検出されるエラーです。文法ミスや型の不一致、セミコロンの付け忘れなどが原因で発生します。

int x = 10
// セミコロンがないためエラー

コンパイルエラーはコンパイル時に検出されるため、プログラムは実行されません。エラーメッセージをもとに修正して再コンパイルする必要があります。

ランタイムエラー

ランタイムエラーは、プログラム実行中に発生するエラーです。文法上は正しいためコンパイルは通りますが、実行中に異常な動作が起こる場合です。

int[] arr = new int[5];
System.out.println(arr[10]);  // ArrayIndexOutOfBoundsException

他にも「0で割る」「nullオブジェクトを参照する」などが典型的な例です。これらは実行時に例外(Exception)として発生し、プログラムが強制終了することがあります。

論理エラー

論理エラーは、プログラムが正常に動作はするが、意図した結果が得られないエラーです。文法的にも実行的にも問題がないため、コンパイラやJVMは検出できません。

int total = 10;
int average = total / 3; // 平均を計算したつもりが整数除算で誤った結果

このようなエラーは、人間がロジックを確認し、デバッグやテストを通じて修正する必要があります。

デバッグの基本

デバッグの基本は、プログラムの動作を正しく理解し、問題の原因を一つずつ特定していくことです。まず重要なのは、エラーメッセージをよく読むことです。エラーが発生した箇所や原因のヒントが詳しく表示されるため、焦らず内容を確認しましょう。次に、スタックトレースを確認することで、どのメソッド呼び出しの中で問題が起きたのかを追跡できます。また、IDE(統合開発環境)のデバッガ機能を活用すると、変数の値や処理の流れを一行ずつ確認でき、原因を効率的に探せます。さらに、System.out.printlnによるプリントデバッグも有効で、変数の値や実行状況を出力しながら動作を確かめることができます。これらを組み合わせることで、プログラムの不具合を正確に把握し、的確に修正できるようになります。

    まとめ

    この記事では、Javaプログラミングの基礎として重要な構文とデータ型について詳しく解説しました。Javaのプログラムは、クラスとメソッドによって構成され、明確な構造のもとで動作します。

    データを扱う際には、8つの基本的なプリミティブ型と、オブジェクトを扱う参照型の2種類が存在します。変数は使用する前に必ず宣言し、必要に応じて初期化することが基本です。また、演算子を使うことで、さまざまな計算や処理を効率的に行うことができます。

    さらに、条件分岐や繰り返しといった制御構造を利用して、プログラムの流れを柔軟にコントロールすることも可能です。配列や文字列の操作方法を理解しておくことで、データの管理や処理が一層スムーズになります。最後に、型変換については自動的に行われる場合と明示的に指定する場合があり、これを正しく使い分けることが安定したプログラム作成につながります。

    Javaは強力な言語であり、これらの基本をしっかり理解することで、より複雑なプログラムを作成するための土台が築けます。練習問題に取り組み、実際にコードを書いてみることが上達への近道です。

    演習問題

    初級レベル(3問)

    問題1

    // 以下のコードを完成させて、「Hello, Java World!」と表示するプログラムを作成してください
    public class Main {
        public static void main(String[] args) {
            // ここにコードを記述
        }
    }

    問題2

    // 以下のプログラムに単一行コメントと複数行コメントを追加してください
    public class Main {
        public static void main(String[] args) {
            int number = 10;
            String message = "Java学習中";
            System.out.println(message + " : " + number);
        }
    }

    問題3

    // 整数型の変数xに5、yに3を代入し、その和を表示するプログラムを完成させてください
    public class Main {
        public static void main(String[] args) {
            // ここにコードを記述
        }
    }

    中級レベル(6問)

    問題4

    // 以下のコードを修正し、正しくコンパイル・実行できるようにしてください
    public class Main {
        public static void main(String[] args) {
            int a = 10.5;
            System.out.println("aの値は: " + a);
        }
    }

    問題5

    // プリミティブ型のキャストを行い、double型の値をint型に変換して表示するプログラムを完成させてください
    public class Main {
        public static void main(String[] args) {
            double d = 15.78;
            // ここにキャスト処理を記述
            System.out.println("int型に変換: " + i);
        }
    }

    問題6

    // 配列を使用して、5つの整数を格納し、その合計値を計算して表示するプログラムを作成してください
    public class Main {
        public static void main(String[] args) {
            // ここにコードを記述
        }
    }

    問題7

    // 以下のコードを修正し、配列の内容を正しく表示するようにしてください
    public class Main {
        public static void main(String[] args) {
            String[] fruits = {"apple", "banana", "orange"};
            for (int i = 0; i <= fruits.length; i++) {
                System.out.println(fruits[i]);
            }
        }
    }

    問題8

    // プリミティブ型と参照型の違いを理解するため、以下のコードを完成させてください
    public class Main {
        public static void main(String[] args) {
            int num1 = 10;
            int num2 = num1;
            num2 = 20;
    
            int[] arr1 = {1, 2, 3};
            int[] arr2 = arr1;
            arr2[0] = 100;
    
            System.out.println("num1: " + num1);
            System.out.println("arr1[0]: " + arr1[0]);
        }
    }

    問題9

    // 異なるプリミティブ型同士の演算と自動型変換について理解するプログラムを完成させてください
    public class Main {
        public static void main(String[] args) {
            int i = 10;
            double d = 5.5;
            // int型とdouble型の演算
            System.out.println("演算結果: " + result);
        }
    }

    上級レベル(3問)

    問題10

    // メソッドのオーバーロードとプリミティブ型のキャストを組み合わせたプログラムを作成してください
    public class Main {
        // 2つのint型を受け取るaddメソッド
        public static int add(int a, int b) {
            return a + b;
        }
    
        // 2つのdouble型を受け取るaddメソッド
        public static double add(double a, double b) {
            return a + b;
        }
    
        public static void main(String[] args) {
            // 様々な型でaddメソッドを呼び出し、結果を表示
        }
    }

    問題11

    // 多次元配列を使用して、3x3の行列を作成し、すべての要素の合計を計算するプログラムを作成してください
    public class Main {
        public static void main(String[] args) {
            // 3x3の二次元配列を宣言・初期化
            // すべての要素の合計を計算して表示
        }
    }

    問題12

    // プリミティブ型のラッパークラスとオートボクシング・アンボクシングを理解するプログラムを完成させてください
    public class Main {
        public static void main(String[] args) {
            // Integerクラスを使用したオートボクシング
            Integer num1 = 100; // オートボクシング
    
            // 明示的なボクシングとアンボクシング
            int num2 = num1; // アンボクシング
    
            // ラッパークラスのメソッドを使用
            String str = "123";
            int num3 = Integer.parseInt(str);
    
            System.out.println("num1: " + num1);
            System.out.println("num2: " + num2);
            System.out.println("num3: " + num3);
        }
    }

    初級レベル(3問)解答例

    問題1 解答例

    // 以下のコードを完成させて、「Hello, Java World!」と表示するプログラムを作成してください
    public class Main {
        public static void main(String[] args) {
            System.out.println("Hello, Java World!");
        }
    }

    問題2 解答例

    // 以下のプログラムに単一行コメントと複数行コメントを追加してください
    public class Main {
        public static void main(String[] args) {
            // これは単一行コメントです
            int number = 10;
            String message = "Java学習中";
    
            /*
             * これは複数行コメントです
             * 複数行にわたる説明を記述できます
             */
            System.out.println(message + " : " + number);
        }
    }

    問題3 解答例

    // 整数型の変数xに5、yに3を代入し、その和を表示するプログラムを完成させてください
    public class Main {
        public static void main(String[] args) {
            int x = 5;
            int y = 3;
            int sum = x + y;
            System.out.println("合計: " + sum);
        }
    }

    中級レベル(6問)解答例

    問題4 解答例

    // 以下のコードを修正し、正しくコンパイル・実行できるようにしてください
    public class Main {
        public static void main(String[] args) {
            double a = 10.5; // int型からdouble型に変更
            System.out.println("aの値は: " + a);
        }
    }

    問題5 解答例

    // プリミティブ型のキャストを行い、double型の値をint型に変換して表示するプログラムを完成させてください
    public class Main {
        public static void main(String[] args) {
            double d = 15.78;
            int i = (int) d; // 明示的なキャスト
            System.out.println("int型に変換: " + i); // 小数点以下は切り捨て
        }
    }

    問題6 解答例

    // 配列を使用して、5つの整数を格納し、その合計値を計算して表示するプログラムを作成してください
    public class Main {
        public static void main(String[] args) {
            int[] numbers = {10, 20, 30, 40, 50};
            int sum = 0;
    
            for (int i = 0; i < numbers.length; i++) {
                sum += numbers[i];
            }
    
            System.out.println("配列の合計: " + sum);
        }
    }

    問題7 解答例

    // 以下のコードを修正し、配列の内容を正しく表示するようにしてください
    public class Main {
        public static void main(String[] args) {
            String[] fruits = {"apple", "banana", "orange"};
            for (int i = 0; i < fruits.length; i++) { // <= を < に修正
                System.out.println(fruits[i]);
            }
        }
    }

    問題8 解答例

    // プリミティブ型と参照型の違いを理解するため、以下のコードを完成させてください
    public class Main {
        public static void main(String[] args) {
            int num1 = 10;
            int num2 = num1; // 値のコピー
            num2 = 20; // num1には影響しない
    
            int[] arr1 = {1, 2, 3};
            int[] arr2 = arr1; // 参照のコピー
            arr2[0] = 100; // arr1も影響を受ける
    
            System.out.println("num1: " + num1); // 10 (変更されていない)
            System.out.println("arr1[0]: " + arr1[0]); // 100 (変更されている)
        }
    }

    問題9 解答例

    // 異なるプリミティブ型同士の演算と自動型変換について理解するプログラムを完成させてください
    public class Main {
        public static void main(String[] args) {
            int i = 10;
            double d = 5.5;
            double result = i + d; // int型がdouble型に自動変換される
            System.out.println("演算結果: " + result); // 15.5
        }
    }

    上級レベル(3問)解答例

    問題10 解答例

    // メソッドのオーバーロードとプリミティブ型のキャストを組み合わせたプログラムを作成してください
    public class Main {
        // 2つのint型を受け取るaddメソッド
        public static int add(int a, int b) {
            return a + b;
        }
    
        // 2つのdouble型を受け取るaddメソッド
        public static double add(double a, double b) {
            return a + b;
        }
    
        public static void main(String[] args) {
            // 様々な型でaddメソッドを呼び出し、結果を表示
            System.out.println("int + int: " + add(5, 3));
            System.out.println("double + double: " + add(5.5, 3.2));
            System.out.println("int + double: " + add(5, 3.2)); // intがdoubleに自動変換
            System.out.println("キャスト使用: " + add((int)5.7, 3)); // 明示的キャスト
        }
    }

    問題11 解答例

    // 多次元配列を使用して、3x3の行列を作成し、すべての要素の合計を計算するプログラムを作成してください
    public class Main {
        public static void main(String[] args) {
            // 3x3の二次元配列を宣言・初期化
            int[][] matrix = {
                {1, 2, 3},
                {4, 5, 6},
                {7, 8, 9}
            };
    
            // すべての要素の合計を計算して表示
            int total = 0;
            for (int i = 0; i < matrix.length; i++) {
                for (int j = 0; j < matrix[i].length; j++) {
                    total += matrix[i][j];
                }
            }
    
            System.out.println("3x3行列の合計: " + total);
        }
    }

    問題12 解答例

    // プリミティブ型のラッパークラスとオートボクシング・アンボクシングを理解するプログラムを完成させてください
    public class Main {
        public static void main(String[] args) {
            // Integerクラスを使用したオートボクシング
            Integer num1 = 100; // オートボクシング(int → Integer)
    
            // 明示的なボクシングとアンボクシング
            Integer num4 = Integer.valueOf(200); // 明示的ボクシング
            int num2 = num1; // アンボクシング(Integer → int)
    
            // ラッパークラスのメソッドを使用
            String str = "123";
            int num3 = Integer.parseInt(str); // 文字列をintに変換
    
            System.out.println("num1: " + num1);
            System.out.println("num2: " + num2);
            System.out.println("num3: " + num3);
            System.out.println("num4: " + num4);
    
            // 比較の例
            Integer a = 127;
            Integer b = 127;
            System.out.println("a == b: " + (a == b)); // true(-128〜127はキャッシュされる)
    
            Integer c = 200;
            Integer d = 200;
            System.out.println("c == d: " + (c == d)); // false(キャッシュ範囲外)
            System.out.println("c.equals(d): " + c.equals(d)); // true
        }
    }