はじめに
Javaのクラスを学ぶ近道は、構文を丸暗記することではなく、データと処理を同じ単位にまとめる考え方を小さなサンプルコードで確認することです。初心者向けの学習ガイドとして、クラスの作り方、使い方、カスタマイズ、注意点、テスト方法までを同じ流れで整理します。
その流れを押さえると、class、new、extends、private、publicの意味がつながり、Javaプログラミングで何をどこに書くべきか判断しやすくなります。公式ドキュメントによれば、Javaのクラス宣言はフィールド、メソッド、コンストラクタなどを含められる構造として説明されているのが基本です。
- Java SE 21 / JDK 21
- JUnit Jupiter 5.10.2
- Spring Framework 7.0系の公式リファレンスを参照
- Javaのクラス、オブジェクト、メソッド、コンストラクタの関係
- 初心者向けのサンプルコードを使ったクラスの作り方
- 継承、カプセル化、オーバーライドによるカスタマイズの考え方
- 注意点を踏まえた設計と、JUnitを使ったテスト方法
- 標準ライブラリやフレームワークへ進むための学習ガイド
この入門を読み進める前に、Java公式のClassesと、標準APIのjava.lang.Objectを参照できる状態にしておくと、用語の確認がしやすくなります。内部の関連資料では、コレクションに進む前の補助としてJava List型完全ガイドも役立ちます。
| 項目 | 主な書き方 | 役割 | 初心者向けの確認点 | 関連する注意点 |
|---|---|---|---|---|
| クラス | class | データと処理の設計図を作る | ファイル名とpublicクラス名をそろえる | 責任を詰め込みすぎない |
| オブジェクト | new | クラスから実体を作る | null参照に注意する | 生成前にメソッドを呼ばない |
| フィールド | String name | 状態を保持する | 型と初期値を確認する | privateで保護する |
| メソッド | void greet() | 処理を名前でまとめる | 戻り値の型を見る | 長すぎる処理を避ける |
| コンストラクタ | Person(...) | 生成時に初期化する | クラス名と同じ名前にする | 必須値を受け取る |
| アクセス修飾子 | public/private | 見える範囲を制御する | 外部公開を最小にする | 直接代入を増やさない |
| 継承 | extends | 既存の性質を引き継ぐ | 親子関係が自然か見る | 深い階層を避ける |
| オーバーライド | @Override | 親の処理を置き換える | メソッド名と引数を一致させる | 注釈で誤記を検出する |
| カプセル化 | getter/setter | 状態変更を管理する | 不正値を防ぐ | 全フィールド公開を避ける |
| 静的メンバー | static | クラス単位で共有する | インスタンスとの差を見る | 共有状態の変更に注意する |
| 定数 | final | 変更しない値を表す | 大文字名が多い | 可変オブジェクトに注意する |
| 配列 | String[] | 同じ型を並べる | 添字は0から始まる | 範囲外参照を避ける |
| List | ArrayList | 要素数を変えられる | importを確認する | 型パラメータを付ける |
| パッケージ | package | クラスを分類する | ディレクトリ構成と合わせる | 同名衝突を避ける |
| インポート | import | 別パッケージを使う | 未使用を整理する | ワイルドカードを乱用しない |
| main | public static void main | 起動点になる | 引数はString[] args | クラス単体には不要な場合もある |
| 戻り値 | return | 処理結果を返す | voidとの違いを見る | 返し忘れに注意する |
| 条件分岐 | if/else | 条件で処理を変える | 比較演算子を見る | ==とequalsを混同しない |
| 繰り返し | for/while | 同じ処理を反復する | 終了条件を決める | 無限ループを避ける |
| 例外 | try/catch | 異常系を扱う | 握りつぶさない | 原因をログに残す |
| 抽象化 | abstract | 共通部分を定義する | 直接生成できない | 過剰設計を避ける |
| インターフェース | interface | 振る舞いの約束を作る | implementsで使う | 責務を明確にする |
| アノテーション | @Test | 付加情報を与える | JUnitでよく使う | 依存関係を確認する |
| アサーション | assertEquals | 期待値を確かめる | 失敗時メッセージを書く | 境界値を含める |
| デバッグ出力 | System.out.println | 値を一時確認する | 消し忘れに注意する | ログへ置き換える |
| ライブラリ | java.util | 既存機能を使う | 標準APIから試す | 互換性を見る |
| フレームワーク | SpringApplication.run | アプリの土台を使う | 依存関係を整える | 学習範囲を分ける |
| シングルトン | getInstance | 生成数を制御する | 単純例から理解する | マルチスレッドでは注意する |
| ファイル名 | HelloWorld.java | ソースを保存する | 大文字小文字を合わせる | クラス名とずらさない |
| コンパイル | javac | バイトコードを作る | エラー行を見る | パッケージ指定に注意する |
Javaとは
Javaは、オブジェクト指向を中心に設計されたプログラミング言語で、ソースコードをjavacでコンパイルし、生成されたバイトコードをJVM上で動かします。そのため、Javaの学習では文法と同時に、クラス単位でプログラムを整理する発想が早い段階から必要になります。
一般に、Javaの特徴はプラットフォーム独立性、標準ライブラリの広さ、自動メモリ管理、型安全性に整理できるのが目安です。Garbage Collectionが不要になったオブジェクトを回収し、java.utilやjava.timeなどのAPIが日常的な処理を支えます。
ただし、初心者がつまずきやすいのは、Javaのファイル、クラス、メソッドの境界が最初から厳密に見える点です。HelloWorld.javaにpublic class HelloWorldを書く理由を理解すると、Javaプログラミングの入口がかなり整理できます。
結果: 期待される出力はHello Worldです。mainメソッドが起動点となり、System.out.printlnが文字列を標準出力へ送りますし、ここがポイントです。
この最小例では、Javaのpublic、static、void、String[]が一度に出てきます。すべてを同時に覚えるより、クラスの外枠、起動メソッド、表示処理という順で読むと理解しやすくなります。
同様に、アノテーションへ進む場合はJavaアノテーションの12選を併読すると、@Overrideや@Testがなぜ使われるのかを確認できるのがポイントです。Javaのクラス学習は、こうした周辺機能と切り離さずに進めるほうが現実的です。
クラスとは
クラスは、オブジェクトの状態と振る舞いをまとめる設計図です。Javaではfieldで状態を持ち、methodで処理を表し、必要に応じてconstructorで初期値を受け取ります。
これを車の例に置き換えると、ブランドや速度が状態で、加速する処理が振る舞いになります。その関係をクラスとして書くと、同じ設計から複数のオブジェクトを作れるため、Javaプログラミングの再利用性が高まりますが、これは押さえたい点です。
その設計図という表現は抽象的に見えますが、実際にはフィールド名、型、メソッド名、引数、戻り値の組み合わせです。クラスを読むときは、どのデータを持ち、どの操作を公開し、どの状態を外から隠すのかを確認すると、初心者向けのサンプルコードでも実用的な読み方に近づきます。
結果: このクラス定義だけでは標準出力はありません。Carオブジェクトを作り、accelerateを呼ぶとspeedの値が増える構造になります。
その構造を確認するには、new Car()でインスタンスを作成し、フィールドへ値を入れてからメソッドを呼びますし、これが一つの目安です。初心者向けのサンプルコードでは、最初はprivateを付けずに動きを見て、その後でカプセル化へ進むと差が分かります。
結果: 期待される出力はSample Motors: 50です。speedに入っていた40へ10が加算されます。
一方、継承を使うと既存クラスの性質を引き継げますが、覚えておくと役立つでしょう。Javaではextendsを使い、親クラスのフィールドやメソッドを子クラスから扱える形にします。
結果: この定義だけでは出力はありません。ElectricCarはCarのaccelerateを使いながら、rechargeでバッテリー量も扱えます。
ただし、継承は似ているから使うものではなく、親の一種として扱える場合に向きますし、ここを基本と考えるとよいでしょう。Javaのクラス設計では、共通化したい処理があるだけなら、継承より委譲やインターフェースのほうが扱いやすい場面もあります。
クラスの作り方
Javaでクラスを作るときは、ファイル名、クラス名、アクセス修飾子、フィールド、メソッドを順番に確認します。publicなトップレベルクラスは、原則としてファイル名と同じ名前にする必要があるのが一般的です。
具体的には、MyClass.javaにpublic class MyClassを書き、内部に変数と処理を置きます。サンプルコードを小さく保つと、Java初心者向けの学習でも構文エラーの位置を追いやすくなります。
このとき、クラス名は大文字で始めるUpperCamelCase、メソッド名や変数名は小文字で始めるlowerCamelCaseが一般的です。名前の付け方をそろえると、Javaプログラミングのコードレビューや検索がしやすくなり、後から読む人にも責務が伝わりますし、ここがポイントです。
基本的なクラスの作成
結果: クラス定義だけでは出力はありません。myMethodを別の起動用クラスから呼ぶと、期待される出力はHello, World!です。
このコードでは、int myVariableがフィールド、public void myMethod()がメソッドです。voidは値を返さないことを表し、System.out.printlnは標準出力へ文字列を送ります。
結果: 期待される出力はHello, World!です。new MyClass()で作成したインスタンスからmyMethodを呼び出します。
メソッドの追加
メソッドは、クラスに持たせたい処理へ名前を付ける仕組みです。Javaではアクセス修飾子 戻り値の型 メソッド名(引数)の形を取り、処理のまとまりを再利用しやすくするのが現実的です。
結果: これは構文の型を示す擬似コードなので、単独ではコンパイル対象ではありません。実際のJavaコードではpublic int add(int a, int b)のように具体的な型へ置き換えます。
このとき、returnが必要かどうかは戻り値の型で決まります。voidなら返す値はなく、intやStringなら対応する値を返す必要があると整理できます。
結果: 期待される出力はHello, World!です。greetに表示処理をまとめ、mainから呼び出しています。
コンストラクタの利用
コンストラクタは、オブジェクト生成時に初期化処理を行う特別な構文です。Javaではクラス名と同じ名前で宣言し、戻り値の型を書きません。
そのため、必ず必要な値をコンストラクタで受け取る設計にすると、生成直後から意味のある状態を保てます。初心者がつまずきやすいのは、this.nameと引数のnameの違いです。
結果: このクラス定義だけでは出力はありません。new Person("Yamada", 25)のように作成すると、nameとageが初期化されますが、これは押さえたい点です。
結果: 期待される出力はName: YamadaとAge: 25です。コンストラクタへ渡した値が、インスタンスのフィールドに入ります。
ただし、学習用の短いサンプルコードではフィールドを直接参照していても、実用的なJavaプログラミングではprivateにしてメソッド経由で扱う設計が一般的です。カスタマイズへ進むと、値の検査や変更制限を入れやすくなります。
クラスの使い方
クラスの使い方は、インスタンスを作り、状態を入れ、メソッドを呼ぶ流れで整理できると理解できます。Javaではnewによってヒープ上にオブジェクトが作られ、変数にはその参照が入ります。
これを理解すると、同じPersonクラスから複数の人物オブジェクトを作れる理由が見えます。Java初心者向けの学習ガイドでは、最初に直接フィールドを操作し、その後でカプセル化へ移る構成が分かりやすいです。
この使い方では、変数そのものがオブジェクト本体ではなく参照である点も押さえますし、これが一つの目安です。別の変数へ同じ参照を代入すると、片方から変更した状態がもう片方からも見えるため、オブジェクトの共有には注意点があります。
インスタンスの作成
結果: クラス定義だけでは出力はありません。showInfoを呼ぶと、オブジェクトが持つnameとageを表示する構造です。
結果: 期待される出力は名前: Tanakaと年齢: 30です。personが参照するインスタンスに値を入れてから、showInfoを呼んでいます。
結果: これは期待される出力例です。コードではなく表示例として読むと、showInfoが何を出すのか確認できます。
このような直接代入は学習段階では扱いやすい一方、値の検査が入れにくいという注意点があると覚えるとよいでしょう。実装パターンとしてよく見るのは、privateフィールドとsetAgeのようなメソッドを組み合わせる形です。
クラスの継承
継承は、既存のクラスを土台にして新しいクラスを定義する仕組みです。Javaではextendsを使い、親クラスの公開されたメソッドを子クラス側から利用できます。
そのため、共通の名前や年齢をPersonへ置き、学生固有の学校名をStudentへ置くような整理ができます。オーバーライドと組み合わせる場合は、Javaでマスターするオーバーライドも関連すると考えられます。
結果: クラス定義だけでは出力はありません。StudentはPersonのintroduceを引き継ぎ、独自にshowSchoolも持ちます。
結果: 期待される出力は名前はTaro Tanaka、年齢は20歳です。と学校はABC Universityです。です。親クラス由来の処理と子クラス固有の処理を続けて呼びます。
💡 Tips: 継承の判断では、StudentがPersonの一種と自然に言えるかを確認します。単に処理を借りたいだけなら、別クラスをフィールドとして持つ設計も候補になると言えるでしょう。
クラスのカスタマイズ
クラスのカスタマイズでは、外部に見せる部分と内部で守る部分を分けます。Javaではprivateフィールド、publicメソッド、必要に応じたfinalやstaticを使い分けます。
その分け方を覚えると、値がどこから変更されるのか追いやすくなるのが基本です。注意点として、すべてのフィールドに無条件のsetterを用意すると、結局どこからでも状態を変えられる構造になりがちです。
具体的には、外部から参照してよい値にはgetterを置き、変更が必要な値だけにsetterを置きます。変更時に条件を入れれば、不正な値が入る前に止められるため、Javaのクラスは単なる入れ物ではなく、状態を守る境界として機能します。
プロパティの追加
結果: クラス定義だけでは出力はありません。displayInfoを呼ぶと、期待される表示は名前と年齢を並べた文字列です。
このカスタマイズでは、nameとageをprivateにして外部からの直接変更を防ぎます。setAgeに条件分岐を入れることで、負の年齢を受け取ったときにIllegalArgumentExceptionを投げられます。
結果: 期待される出力は名前: Taro Yamada, 年齢: 25と名前: Taro Yamada, 年齢: 26です。setAgeを通して状態が変わりますが、覚えておくと役立つでしょう。
メソッドのオーバーライド
オーバーライドは、親クラスで定義されたメソッドを子クラスで再定義する仕組みです。Javaでは@Overrideを付けると、メソッド名や引数の誤りをコンパイル時に検出しやすくなります。
結果: 期待される出力はDog soundとCat soundです。変数の型はAnimalでも、実体のクラスに応じたメソッドが呼ばれます。
この動きはポリモーフィズムと呼ばれます。Javaのクラスをカスタマイズするとき、共通の型で扱いながら動作だけ変えたい場面で役立ちますし、ここを基本と考えるとよいでしょう。
クラスの応用例
クラスの基礎を押さえた後は、設計パターン、標準ライブラリ、フレームワークへ広げると実用的な使い方が見えてきます。Javaの応用では、クラス同士の依存関係を整理し、変更に強い構造を作ることが中心になります。
たとえば日付処理であればJavaでうるう年を判定する解説、文字列処理であればJavaエスケープ処理のガイドのように、テーマ別にクラスの使い方を確認すると理解が深まりますし、ここがポイントです。
その応用で意識したいのは、設計パターンを覚えること自体ではなく、問題の形を言語化することです。同じオブジェクトを共有したい、処理を差し替えたい、生成手順を隠したいなどの目的が明確になると、Javaのクラス設計で選ぶべき構造が判断しやすくなります。
デザインパターンとクラスの関係
デザインパターンは、よく出る設計上の問題に名前を付けたものです。Javaのクラスでは、生成方法、振る舞いの切り替え、責務の分離などをパターンとして整理できます。
結果: クラス定義だけでは出力はありません。getInstanceを通すと、同じSingletonインスタンスを返す構造になるのが目安です。
ただし、この単純なシングルトンはマルチスレッド環境で同時生成の問題が起きる可能性があります。学習用のサンプルコードとして仕組みを読むのに向いていますが、実用ではenumや初期化タイミングを制御する別実装も検討します。
結果: 期待される出力はtrueです。singleton1とsingleton2が同じ参照を持つため、==の比較が真になるのがポイントです。
ライブラリとフレームワークの利用
ライブラリは必要な機能を呼び出して使う部品群で、フレームワークはアプリケーション全体の流れを支える土台です。Javaの標準ライブラリならArrayListやHashMap、フレームワークならSpringが代表例になります。
結果: 期待される出力はJavaとクラスです。ArrayListへ追加した順に、拡張for文で取り出しています。
結果: Spring Bootの依存関係が整っている場合、期待される動作はアプリケーション起動です。@SpringBootApplicationが起動設定の入口になり、SpringApplication.runがアプリケーションを開始します。
公式のSpring Frameworkでは、Javaベースのエンタープライズアプリケーション向けのプログラミングモデルが提供されています。学習ガイドとしては、標準ライブラリ、JUnit、Springの順に進むと、クラスの使い方が段階的につながりますが、これは押さえたい点です。
注意点と対処法
Javaのクラス設計で特に押さえたいのは、責務、可視性、変更範囲です。ひとつのクラスに入力、計算、表示、保存をすべて詰め込むと、変更時に影響範囲が広がります。
そのため、クラス名は役割を表す名詞にし、メソッド名は処理を表す動詞に寄せるのが一般的です。UserValidator、OrderService、calculateTotalのように名前を付けると、プログラミング中に責務のずれを見つけやすくなります。
publicクラスを同じ枠へ載せる場合があるのが一般的です。実際にファイルへ分けるときは、Person.java、Student.java、Main.javaのようにクラス単位で保存します。適切なクラス設計の考え方
単一責任の原則は、クラスが持つ変更理由をできるだけ少なくする考え方です。Javaの初心者向け教材では抽象的に見えますが、入力チェック、計算、出力を別メソッドや別クラスに分けるだけでも効果を確認できます。
一方、開放/閉鎖原則は、既存コードを書き換えずに拡張できる設計を目指するのが現実的です。たとえばinterfaceを使って振る舞いを差し替えられるようにすると、既存の利用側コードを小さく保てます。
具体的には、依存関係を抽象型に向けると、テスト用の実装や別の実装へ差し替えやすくなります。この注意点は、後からJUnitでテストを書くときにも効いてきますし、これが一つの目安です。
- クラスはひとつの責務に寄せ、名前と処理を一致させる
- フィールドは原則として
privateにし、必要な操作だけ公開する - 継承よりも委譲や
interfaceが自然な場面を見分ける null、境界値、例外の扱いをメソッド単位で決める
クラス設計の注意点
初心者がつまずきやすいのは、フィールドをすべて公開し、どのクラスからでも変更できる形にしてしまう点です。短いサンプルコードでは動いても、処理が増えるほど不正な値の混入を追いにくくなります。
その対処法として、コンストラクタで必須値を受け取り、変更可能な値だけにsetterを用意します。さらに、ifで範囲を確認し、不正値にはIllegalArgumentExceptionを返すと原因が分かりやすくなると整理できます。
ただし、例外を多用すれば設計が良くなるわけではありません。入力値の制約、呼び出し側の責任、エラーメッセージの内容をそろえておくと、Javaプログラミングの保守がしやすくなります。
==ではなくequalsを使うのが一般的です。==は参照の同一性を見ており、内容比較とは意味が異なります。クラスのテスト方法
クラスのテストでは、メソッドへ入力を渡し、期待値と返り値を比較すると理解できます。JavaではJUnitが広く使われ、公式のJUnit 5 User Guideでアノテーションやアサーションの使い方を確認できます。
このとき、テスト対象のクラスとテストクラスを分けると、プログラミング上の責務が明確になります。サンプルコードではMyClassに計算処理を置き、MyClassTestでassertEqualsを使って期待値を確かめますが、覚えておくと役立つでしょう。
ユニットテストの導入
結果: 期待される結果は、両方のテストが成功することです。失敗した場合は、JUnitのレポートに期待値と実際の値の差が示されます。
この例では、@Testがテストメソッドを示し、assertEqualsが期待値と計算結果を比較します。Javaのクラスを変更した後に同じテストを走らせると、既存の使い方を壊していないか確認できると覚えるとよいでしょう。
デバッグの方法
デバッグでは、値の流れ、条件分岐、例外発生箇所を順に追います。小さな学習用コードではSystem.out.printlnでも確認できますが、アプリケーションが大きくなるとIDEのブレークポイントやログ出力へ移すほうが扱いやすくなります。
結果: 期待される出力はresultの値は: 15です。aとbの合計がresultに入っていることを表示で追えますし、ここを基本と考えるとよいでしょう。
もっとも、確認用の出力を本番コードに残すとログが読みにくくなります。Javaの実務的なコードでは、ロガー、テスト、例外メッセージを組み合わせ、問題の原因を再現しやすい形に整えます。
まとめ
Javaのクラスは、フィールドで状態を持ち、メソッドで振る舞いを表し、コンストラクタで初期化する単位です。初心者向けの学習ガイドでは、最小のクラスから始め、インスタンス化、継承、カスタマイズ、テストへ順に広げると理解がつながりますし、ここがポイントです。
その過程で大切になるのは、サンプルコードをただ写すのではなく、class、new、this、extends、@Overrideが何を担っているかを説明できる状態にすることです。Javaプログラミングでは、構文の暗記よりもクラス同士の責務を整理する視点が長く役立ちます。
これらの基礎が固まったら、標準ライブラリ、例外処理、コレクション、JUnit、Springのようなフレームワークへ進むと、Javaの使い方が実装全体の流れとして見えてきます。注意点を意識しながら小さく動かし、カスタマイズとテストを組み合わせるのが、クラス学習の現実的な進め方です。
関連記事
- Java List型完全ガイド!初心者でもマスターできる7つのステップ
- Javaアノテーションの12選!初心者から上級者まで徹底ガイド
- Javaでうるう年を判定!初心者でも分かる9ステップ解説
- Javaエスケープ処理の10ステップマスターガイド
- Javaでマスターする!オーバーライドのたった7つのステップ
※本記事は実在のエンジニア複数名で構成される Japanシーモア編集部が、AI支援を活用して作成・校正・公開しています。


