この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:6
ページ更新者:guest
更新日時:2026-06-11 07:07:02

タイトル: インスタンス化
SEOタイトル: インスタンス化完全ガイド — new・コンストラクタ・ファクトリ

この記事の要点
  • インスタンス化=クラスから実体 (オブジェクト) を生成すること
  • Java/PHP/C# は new ClassName(args) 記法。Python は ClassName(args) (new 不要)
  • 引数なしコンストラクタを明示しないと 暗黙のデフォルトコンストラクタが生成される (他のコンストラクタが 1 つでもあれば生成されない)
  • ファクトリメソッド: User.of(...) 等で名前付き生成。new より読みやすく、キャッシュ・サブクラス返却が可能
  • Singletonはコンストラクタを private にして new を防ぐ。DI コンテナでは new をフレームワークに任せる

インスタンス化とは

クラス (設計図) からオブジェクト (実体) を生成する操作。Java では new キーワードを使います。

public class User {
    private String name;
    private int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

// インスタンス化
User u = new User("Taro", 25);
//          ↑ new キーワード + コンストラクタ呼び出し
//
// 内部的に:
//   1. ヒープにメモリ確保 (User 1 個分)
//   2. フィールドを既定値で初期化 (name=null, age=0)
//   3. コンストラクタを呼び出してフィールド設定
//   4. オブジェクトの参照を u に代入

言語別の書き方比較

言語インスタンス化備考
JavaUser u = new User("Taro");明示的な new
PHP$u = new User("Taro");Java と同じ
C#var u = new User("Taro");Java と同じ
Pythonu = User("Taro")new 不要 (関数呼び出しと同じ)
JavaScriptconst u = new User("Taro");ES6 class
Rubyu = User.new("Taro")クラスのクラスメソッド
Kotlinval u = User("Taro")new 不要
// PHP
class User {
    public function __construct(
        public string $name,
        public int $age = 0,
    ) {}
}
$u = new User("Taro", 25);
$u = new User(name: "Taro");        // 名前付き引数 (PHP 8+)
# Python
class User:
    def __init__(self, name, age=0):
        self.name = name
        self.age = age

u = User("Taro", 25)       # new 不要
u = User(name="Taro")      # 名前付き引数

引数なしコンストラクタの自動生成

// ① コンストラクタを書かない場合
public class A { }
// → コンパイラが暗黙で「引数なし public コンストラクタ」を生成
A a = new A();   // ✅ OK

// ② 1 つでもコンストラクタを書いた場合
public class B {
    public B(String s) { }
}
// → 暗黙のデフォルトコンストラクタは ★ 生成されない
B b = new B();         // ★ コンパイルエラー
B b = new B("hello");  // OK

// ③ 引数なしを保持したい場合は明示
public class C {
    public C() { }            // 明示する
    public C(String s) { }
}

引数渡しの注意 (値渡し / 参照渡し)

public class Box {
    public int value;
    public Box(int v) { this.value = v; }
}

void f(int n)   { n = 999; }            // 基本型は値のコピー
void g(Box b)   { b.value = 999; }      // 参照のコピー → 中身は変わる
void h(Box b)   { b = new Box(0); }     // 参照を別物に → 呼び出し側に影響なし

int x = 1;
f(x);
System.out.println(x);  // 1 (影響なし)

Box box = new Box(1);
g(box);
System.out.println(box.value);  // 999 (中身書き換え)

Box box2 = new Box(1);
h(box2);
System.out.println(box2.value); // 1 (参照差し替えは伝わらない)

ファクトリメソッドパターン

new の代わりに名前付き static メソッドで生成する設計:

public class User {
    private String name;
    private boolean isAdmin;

    private User(String name, boolean isAdmin) {
        this.name = name;
        this.isAdmin = isAdmin;
    }

    // ファクトリメソッド (意図が読み手に伝わる)
    public static User createGuest(String name) {
        return new User(name, false);
    }

    public static User createAdmin(String name) {
        return new User(name, true);
    }

    public static User fromEmail(String email) {
        return new User(email.split("@")[0], false);
    }
}

User u1 = User.createGuest("Taro");
User u2 = User.createAdmin("admin");
User u3 = User.fromEmail("taro@example.com");

ファクトリの利点:

  • 名前で意図を表現できる (new User(true) → 何の true?)
  • キャッシュを返せる (Integer.valueOf(1) は -128〜127 を共有)
  • サブクラスを返せる (戻り値型は抽象、実装は具象)
  • コンストラクタを private にすれば new を完全に隠せる

リフレクションでインスタンス化

// クラス名 (文字列) からインスタンス生成
Class cls = Class.forName("com.example.User");

// Java 9+ 推奨: getDeclaredConstructor + newInstance
Object u = cls.getDeclaredConstructor(String.class, int.class)
              .newInstance("Taro", 25);

// 引数なしのコンストラクタなら
Object u2 = cls.getDeclaredConstructor().newInstance();

// 旧来 (Java 9 で deprecated)
// Object u3 = cls.newInstance();

// 用途: フレームワーク (Spring DI / JUnit / Jackson) の内部実装

Singleton: new を防ぐ

public class AppConfig {
    private static final AppConfig INSTANCE = new AppConfig();

    private AppConfig() { }   // ★ private → 外から new できない

    public static AppConfig getInstance() {
        return INSTANCE;
    }
}

// 利用
AppConfig cfg = AppConfig.getInstance();
// AppConfig cfg2 = new AppConfig();  // ★ コンパイルエラー

// Java 5+ では enum Singleton が推奨
public enum AppConfig {
    INSTANCE;
    public void load() { ... }
}
AppConfig.INSTANCE.load();

DI (依存性注入) でインスタンス生成をフレームワークに任せる

@Service
public class UserService {
    private final UserRepository repo;

    // ★ new ではなくフレームワークが自動注入
    public UserService(UserRepository repo) {
        this.repo = repo;
    }
}

// アプリ側は new しない
@Autowired
private UserService userService;

// DI の利点:
// - テスト時にモックを差し替えやすい
// - ライフサイクル管理を Spring が肩代わり
// - 設定で実装クラスを切替可能

FAQ

Q: new を忘れるとどうなる?
A: Java はコンパイルエラーになり気付ける。Python は普通の関数呼び出しと同じ書式なので「忘れる」概念がない。

Q: 引数なしコンストラクタが必要なケース
A: JPA / Hibernate / Jackson 等のフレームワークがリフレクションで生成するため、引数なし public コンストラクタが要求されることがある。

Q: final クラスでもインスタンス化できる?
A: できる。final class継承不可を意味するだけで、new は問題なく可能。