---
title: Enum、お前は一体何者だ？
tags: 
author: [hirotaka kono](https://www.docswell.com/user/hk_it7)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/GJWZ59RQJ2.jpg?width=480
description: BuriKaigi 2026 登壇資料 『Enum、お前は一体何者だ？複数言語で見る「列挙型」の多様な進化と使い方』  https://kouno-log.hkono.workers.dev/
published: January 10, 26
canonical: https://www.docswell.com/s/hk_it7/KLVM77-enum-burikaigi
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/GJWZ59RQJ2.jpg)

Enum、お前は一体何者だ？
複数言語で見る「列挙型」の多様な進化と使い方


# Page. 2

![Page Image](https://bcdn.docswell.com/page/4EZ1N9R373.jpg)

登壇者、お前は一体何者だ？
河野 裕隆（こうの）
▹ 📛 X: @hk_it7
▹ 🏢 虎の穴ラボ株式会社 でチームリーダー
▹ ☕ ECサイト開発でJavaメインに活動
▹ 💎 ファンクラブ支援サイトをRuby on Railsで開発
▹ 🎤 地域エンジニアコミュニティ、東葛.devを主催


# Page. 3

![Page Image](https://bcdn.docswell.com/page/Y76L8KRZJV.jpg)

今日のアジェンダ
public enum TodaysAgenda {
WHAT_IS_ENUM(&quot;Enumとは&quot;, &quot;定数グループ化、型安全性、保守性&quot;),
JAVA(&quot;クラスインスタンス&quot;, &quot;振る舞いのカプセル化、メソッド定義&quot;),
CSHARP(&quot;整数定数&quot;, &quot;シンプルさ、ビットフラグ、拡張メソッド&quot;),
PHP(&quot;Backed Enum&quot;, &quot;モダン設計、DB連携、後発の利点&quot;),
TYPESCRIPT(&quot;型システム&quot;, &quot;ランタイムとのギャップ、as const推奨&quot;),
RAILS(&quot;フレームワーク機能&quot;, &quot;ActiveRecord統合、DB整合性&quot;);
}
TodaysAgenda.WHAT_IS_ENUM.getDescription(); →


# Page. 4

![Page Image](https://bcdn.docswell.com/page/G7519P89E4.jpg)

Enumとは？
基本概念
定義: 有限の値の集合を表現するデータ型
用途: 状態、カテゴリ、オプション、モードなどの表現
注文ステータス
┌─────────────┐
│ PENDING
│
│ PROCESSING │
│ SHIPPED
│ DELIVERED
│
│
└─────────────┘


# Page. 5

![Page Image](https://bcdn.docswell.com/page/9J2126K57R.jpg)

話そうと思った動機


# Page. 6

![Page Image](https://bcdn.docswell.com/page/DEYZY9N67M.jpg)

私の背景
Javaメインのエンジニア
業務では主にJavaを使用
Railsとの出会い
別プロジェクトにアサインされ、Ruby on Railsを使うことに
→ RailsのEnumとJavaのEnumが全然違う！
「同じ&quot;Enum&quot;なのに、なぜこんなに違うんだろう？」という疑問がずっとあった


# Page. 7

![Page Image](https://bcdn.docswell.com/page/VJN3PLV1J8.jpg)

TSKaigi 2025での気づき
yamanokuさんの発表
「TypeScriptのEnumについて」の発表を聴講
学んだこと
▹ JSにはそもそもEnumがない
▹ TypeScriptのEnumはあまり使われていない
▹ Node.js 25のType Strippingで状況が変化
「TypeScriptのEnumって、JavaやRailsとはまた
違うアプローチなんだ…」


# Page. 8

![Page Image](https://bcdn.docswell.com/page/YE99346YE3.jpg)

PHPのEnumとの出会い
tyamahoriさんとの出会い
文脈: 地域のエンジニアコミュニティで一緒に活動
→ コミュニティの勉強会で技術の話をする仲
Zennの記事を発見
PHPのEnumについての記事
PHP Enumは複数のメンバーを持てない
この違いを整理して話したい！


# Page. 9

![Page Image](https://bcdn.docswell.com/page/GE89MQZK7D.jpg)

なぜEnumなのか？
共通概念 - Enumは全言語に共通する概念
設計思想の違い - しかし実装は全く異なる
型安全性 - この違いから各言語の思想が見える


# Page. 10

![Page Image](https://bcdn.docswell.com/page/LELW3XDPJR.jpg)

Enumがない世界の問題
// 定数での実装の問題
public static final int STATUS_DRAFT = 0;
public static final int STATUS_PUBLISHED = 1;
public static final int STATUS_ARCHIVED = 2;
// 問題1: 型安全性がない
public void setStatus(int status) {
// 999を渡されても防げない
}
// 問題2: 可読性が低い
if (status == 1) {
// 1って何？
}
// 問題3: リファクタリングが困難
問題点
🚫 型安全性の欠如 不正な値の代入を防げない
🚫 可読性の低下 コード上で意味が不明確
🚫 保守性の問題 使用箇所の特定が困難


# Page. 11

![Page Image](https://bcdn.docswell.com/page/4JM9DLP2EW.jpg)

Enumの4つの役割
🛡️ 型安全性の確保
📖 可読性の向上
不正な値の代入を防ぐ
コード上で意味が明確
🔧 保守性の向上
💡 IDEサポート
値の追加・変更が容易
自動補完、リファクタリング


# Page. 12

![Page Image](https://bcdn.docswell.com/page/PJRG4K15E9.jpg)

Enumの歴史：導入時期の比較
言語/FW
バージョン
リリース年
特徴
C#
1.0
2002年
初期から存在。整数ベース
Java
JDK 5.0
2004年
Typesafe Enumパターン→言語機能化
TypeScript
0.9
2013年
Numeric enum。後にString enum追加
Rails
4.1
2014年
ActiveRecord::Enumとして導入
PHP
8.1
2021年
Pure/Backed Enum。最も新しい


# Page. 13

![Page Image](https://bcdn.docswell.com/page/PEXX2LYXEX.jpg)

Enumはクラスか定数か
JavaとC#とPHPでの比較


# Page. 14

![Page Image](https://bcdn.docswell.com/page/3EKWML39ED.jpg)

Java - クラスインスタンス
各Enum定数が振る舞いを持つ
public enum PaymentMethod {
CREDIT_CARD {
public int calculateFee(int amount) {
return (int) (amount * 0.03);
}
},
BANK_TRANSFER {
public int calculateFee(int amount) {
return 200; // 固定200円
}
};
}
public abstract int calculateFee(int amount);
特徴
✅ フィールド複数可能 各定数に複数のフィールドを
持てる
✅ メソッド定義可能 抽象メソッドで振る舞いを強制
✅ ポリモーフィズム 各定数が異なる実装を持てる
⚠️ メモリ効率: ○ クラスインスタンスのためやや重
い


# Page. 15

![Page Image](https://bcdn.docswell.com/page/L731Y3G9J5.jpg)

C# - 整数定数
シンプルかつ効率的なアプローチ
// Flags属性でビットフラグを有効化
[Flags]
public enum Permission
{
None = 0,
// 0000
Read = 1,
// 0001
Write = 2,
// 0010
Delete = 4
// 0100
}
// ビット演算で組み合わせ
var perm = Permission.Read
| Permission.Write;
特徴
✅ 整数のみ 内部的には整数として扱われる
✅ ビットフラグ 複数の値を組み合わせ可能
✅ 拡張メソッド Enum自体を変更せず機能追加
✅ メモリ効率: ◎ 整数定数のため非常に軽量


# Page. 16

![Page Image](https://bcdn.docswell.com/page/87DX5418EG.jpg)

Java vs C# 比較
観点
JAVA
C#
本質
クラスインスタンス
整数定数
メソッド
各定数で実装可能
拡張メソッドで追加
メモリ
やや重い
軽量
ビット演算
不可
Flags属性で簡単
ポリモーフィズム
◎
△（拡張メソッド）
型安全性
◎
△（整数を受け入れる）


# Page. 17

![Page Image](https://bcdn.docswell.com/page/VJPPGMQWJ8.jpg)

設計思想の違い
Java: OOPの原則に忠実
C#: シンプルさと効率性
振る舞いのカプセル化を重視
実用性と拡張性のバランス
▹ Enumは単なる定数ではなく「型」
▹ 基本はシンプルな整数定数
▹ 各定数がオブジェクトとして振る舞いを持つ
▹ ビットフラグで複雑な状態管理
▹ ポリモーフィズムにより柔軟な設計
▹ 拡張メソッドで後から機能追加
▹ 哲学: 正しいOOP設計を追求
▹ 哲学: 実用性とパフォーマンス重視
どちらが優れているということではなく、アプローチの違い


# Page. 18

![Page Image](https://bcdn.docswell.com/page/2EV26959EQ.jpg)

Java - 振る舞いのカプセル化
各Enum定数で異なるロジックを実装
public enum PaymentMethod {
CREDIT_CARD(&quot;クレジットカード&quot;) {
public int calculateFee(int amount) {
return (int) (amount * 0.03); // 3%
}
},
BANK_TRANSFER(&quot;銀行振込&quot;) {
public int calculateFee(int amount) {
return 200; // 固定200円
}
};
private final String displayName;
}
public abstract int calculateFee(int amount);
使用例: switchが不要！
int fee = method.calculateFee(15000);


# Page. 19

![Page Image](https://bcdn.docswell.com/page/57GRNZ64EL.jpg)

Java switch式の網羅性チェック
◎ switch式（推奨）
△ switch文 + default
// 網羅性チェックあり
int fee = switch (method) {
case CREDIT_CARD -&gt;
(int) (amount * 0.03);
case BANK_TRANSFER -&gt; 200;
case CASH_ON_DELIVERY -&gt; 300;
// 新しいEnum値を追加したら
// コンパイルエラーで検知
};
// 網羅性チェックなし
switch (method) {
case CREDIT_CARD:
fee = (int) (amount * 0.03);
break;
case BANK_TRANSFER:
fee = 200;
break;
default:
// 新しいEnum値を追加しても
// 気づけない
fee = 0;
}
推奨: Javaでswitch/caseを使う場合は、switch式を使い、default節を避ける


# Page. 20

![Page Image](https://bcdn.docswell.com/page/4EQVQL4RJP.jpg)

C# - シンプルさと拡張性
ビットフラグと拡張メソッド
// Flags属性でビットフラグを有効化
[Flags]
public enum Permission
{
None = 0,
// 0000
Read = 1,
// 0001
Write = 2,
// 0010
Delete = 4, // 0100
Admin = 8
// 1000
}
// 組み合わせ
var perm = Permission.Read
| Permission.Write;
// 拡張メソッドで機能追加
public static class PermissionExt
{
public static string GetName(
this Permission p)
{
return p switch {
Permission.Read =&gt; &quot;読取&quot;,
Permission.Write =&gt; &quot;書込&quot;,
_ =&gt; &quot;不明&quot;
};
}
}
// 使用
perm.GetName(); // &quot;読取&quot;


# Page. 21

![Page Image](https://bcdn.docswell.com/page/KJ4MNDQQE1.jpg)

PHP - 良いとこ取りのモダンEnum
文字列バッキング値 + メソッド定義
enum OrderStatus: string
{
case PENDING = &#039;pending&#039;;
case PROCESSING = &#039;processing&#039;;
case SHIPPED = &#039;shipped&#039;;
}
// メソッドを定義可能
public function canCancel(): bool
{
return match($this) {
self::PENDING, self::PROCESSING =&gt; true,
default =&gt; false,
};
}
DB連携が簡単: $status-&gt;value で &quot;pending&quot; を取得


# Page. 22

![Page Image](https://bcdn.docswell.com/page/LE185ZPL7G.jpg)

JavaとC#とPHPの比較表
観点
JAVA
C#
PHP
本質
クラス
整数定数
言語機能
フィールド
複数可能
整数のみ
1つのみ
メソッド
○
拡張メソッド
○
ポリモーフィズム
◎
×
△ match式
ビットフラグ
△
◎ Flags
△
DB連携
○
△
◎ 最高
メモリ効率
○
◎
○


# Page. 23

![Page Image](https://bcdn.docswell.com/page/GEWZ592QE2.jpg)

Java、C#、PHPの設計思想
Java
C#
PHP
OOPの原則に忠実
シンプルさと効率性
Web開発の実用性
▹ 振る舞いのカプセル化
▹ 基本はシンプルな整数
▹ DB連携を最優先
▹ 型安全性を最重視
▹ ビットフラグで柔軟性
▹ 後発の利点を活用
▹ ポリモーフィズム重視
▹ 拡張メソッドで機能追加
▹ 実用的なモダン設計
どれが優れているかではなく、要件に合わせて選択することが重要


# Page. 24

![Page Image](https://bcdn.docswell.com/page/47Z1N9D3J3.jpg)

ネイティブでない言語のアプロ
ーチ
TypeScriptとRuby on Railsの工夫


# Page. 25

![Page Image](https://bcdn.docswell.com/page/YJ6L8K1ZEV.jpg)

TypeScript - 型システムのEnum
数値Enum
文字列Enum
enum HttpStatus {
OK = 200,
BadRequest = 400,
NotFound = 404,
}
enum LogLevel {
DEBUG = &quot;DEBUG&quot;,
INFO = &quot;INFO&quot;,
WARN = &quot;WARN&quot;,
ERROR = &quot;ERROR&quot;,
}
function handleResponse(status: HttpStatus) {
// ...
}
handleResponse(HttpStatus.OK); // OK
handleResponse(200); // OK（危険！）
handleResponse(999); // OK（危険！）
function log(level: LogLevel, message: string) {
console.log(`[${level}] ${message}`);
}
log(LogLevel.INFO, &quot;処理開始&quot;); // OK
// log(&quot;INFO&quot;, &quot;処理開始&quot;); // エラー


# Page. 26

![Page Image](https://bcdn.docswell.com/page/GJ519P4974.jpg)

TypeScript Enumの問題点
問題1: 型安全性が危うい
// 数値Enumは数値を直接渡せてしまう
handleResponse(999); // コンパイルエラーにならない！
問題2: リバースマッピングで肥大化
// トランスパイル後のJavaScript
{
OK: 200,
NotFound: 404,
200: &quot;OK&quot;,
// リバースマッピング（不要）
404: &quot;NotFound&quot;
// リバースマッピング（不要）
}
問題3: Tree-shakingが効きにくい


# Page. 27

![Page Image](https://bcdn.docswell.com/page/LE31Y3G275.jpg)

TypeScript 推奨アプローチ
❌ Enum（非推奨）
✅ const object（推奨）
enum LogLevel {
DEBUG = &quot;DEBUG&quot;,
INFO = &quot;INFO&quot;,
}
const LogLevel = {
DEBUG: &quot;DEBUG&quot;,
INFO: &quot;INFO&quot;
} as const;
問題点:
type LogLevel = typeof LogLevel[
keyof typeof LogLevel
];
▹ Tree-shakingが効かない
▹ リバースマッピング
▹ バンドルサイズ増加
function log(
level: LogLevel,
message: string
) { ... }
log(LogLevel.INFO, &quot;OK&quot;); // OK
log(&quot;INVALID&quot;, &quot;NG&quot;); // エラー！


# Page. 28

![Page Image](https://bcdn.docswell.com/page/8EDX5416JG.jpg)

Node.js 25の衝撃
Type Stripping機能の導入
Node.js 25 (2025年10月リリース) でType Stripping機能が安定機能として導入
# Node.js 25でTypeScriptを直接実行
node app.ts
❌ 重大な問題: Enumは動かない
Type Strippingは型を削除するだけで、コード変換は行わない
=&gt; &quot;enum&quot; キーワードを削除できない
SyntaxError: Unexpected token &#039;enum&#039;


# Page. 29

![Page Image](https://bcdn.docswell.com/page/V7PPGM5Z78.jpg)

Node.js 25での正解
機能
TYPE STRIPPING
理由
✅ as const
動作する
純粋なJavaScript
❌ enum
動作しない
コード生成が必要
❌ const enum
動作しない
インライン展開が必要
✅ 唯一の正解: as const
const Status = {
Active: &quot;active&quot;,
Inactive: &quot;inactive&quot;,
} as const;
type Status = (typeof Status)[keyof typeof Status]; // 型定義は削除されるが、ランタイムには影響しない


# Page. 30

![Page Image](https://bcdn.docswell.com/page/2JV269PMJQ.jpg)

Ruby on Rails - フレームワーク主導
規約ベースで多くの機能を自動生成
モデル定義
自動生成されるメソッド
class Article &lt; ApplicationRecord
enum status: {
draft: 0,
published: 1,
archived: 2
}
end
# 状態チェック
article.draft?
article.published?
# =&gt; true/false
# =&gt; true/false
# 状態変更
article.published!
# statusを1に設定
# スコープ
Article.draft
Article.published
# WHERE status = 0
# WHERE status = 1
# 一覧
Article.statuses
# =&gt; {&quot;draft&quot;=&gt;0, ...}


# Page. 31

![Page Image](https://bcdn.docswell.com/page/5EGRNZPXJL.jpg)

Rails 文字列enum推奨
整数enum（レガシー）
文字列enum（推奨）
enum status: {
draft: 0,
published: 1
}
enum status: {
pending: &#039;pending&#039;,
processing: &#039;processing&#039;
}
問題点:
利点:
▹ DB: status = 0 （何？）
▹ DB: status = &#039;pending&#039; （明確！）
▹ 可読性が低い
▹ 可読性が高い
▹ 順序変更で破損
▹ 順序変更に強い
Rails 7+: 文字列enumが推奨


# Page. 32

![Page Image](https://bcdn.docswell.com/page/4JQVQL257P.jpg)

TypeScriptとRailsの対比
TypeScript
Rails
▹ 静的型付け
▹ 動的型付け
▹ コンパイル時チェック
▹ ランタイムチェック
▹ 型安全性優先
▹ 生産性優先
▹ const object推奨
▹ 規約による自動生成
▹ Node.js 25で制約増加
▹ 変わらず高生産性
両極端のアプローチ - それぞれの強みを理解することが重要


# Page. 33

![Page Image](https://bcdn.docswell.com/page/K74MNDLVJ1.jpg)

まとめ


# Page. 34

![Page Image](https://bcdn.docswell.com/page/LJ185ZL4EG.jpg)

本日の学び
1. Enumは単なる定数ではな
い
各言語の設計思想が凝縮されている
2. 型安全性の重要性
Enumは型安全性を実現する強力な手段
3. 後発の利点を活かした設計
PHPはRailsの実用性とJavaの表現力を併せ持つ
4. 他言語を知ることの価値
自分のメイン言語の強みと制約を再認識できる


# Page. 35

![Page Image](https://bcdn.docswell.com/page/GJWZ59VZJ2.jpg)

Enumは単なる定数ではない
各 言語の設計 思想が凝縮さ れた、
型安 全性 と保守性を 実現する強力 な手段である
他言語のEnumを知ることで、
あなたのコーディングに新たな視点と熱意を
ご清聴ありがとうございました


