本ページはプロモーションが含まれています

Java入門

Javaのvarとは?型推論の使い方と使うべき場面を解説

トム

・都内自社開発企業勤務/Javaバックエンドエンジニア
/Java歴10年以上 ・首都圏在住30代
・資格:基本情報技術者/応用情報技術者/Java Silver/Python3エンジニア認定基礎 詳細なプロフィール

Javaのvarとは、Java 10から導入された「ローカル変数型推論」の機能です。

String message = "Hello"; と書いていた型名を省略し、var message = "Hello"; と簡潔に書けるようになります。

特にジェネリクスなど型名が長くなる場面で威力を発揮します。

ただし、使いどころを誤ると可読性が下がり、チーム開発では「var禁止」ルールが設けられることもあります。

この記事を読めば、(1) varが使える場面・使えない場面の全パターン、(2) メリット・デメリットを踏まえて使うべきかを判断する基準、(3) varが「禁止」される現場の理由と対処法まで分かります。

Java歴10年以上の筆者が実務で培った使い分けのコツも交えて解説します。

この記事でわかること

  • varが使える場面・使えない場面の全パターン
  • メリット・デメリットを踏まえて使うべきかを判断する基準
  • varが「禁止」される現場の理由と対処法

Javaのvarとは?型推論が導入された背景

Javaのvarとは何か、型推論が導入された背景を示す図解

var は、Java 10から導入された「ローカル変数型推論」のための機能です。

変数を宣言する際に、型の代わりに var と記述すると、コンパイラが初期化の値から自動的に型を判断(推論)してくれます。

これは、Javaが動的型付け言語になったわけではありません。あくまでコンパイル時に型が決定される静的型付け言語である点は、今までとまったく同じです。

コードの記述量を減らし、より現代的なプログラミングスタイルを可能にするために導入されました。

varが使えるバージョンはJava 10から

var は、2018年にリリースされた Java 10(2026年時点で導入から約8年)で JEP 286(Local-Variable Type Inference)として正式に導入されました。

そのため、Java 9以前の環境では使用できません。

長期サポート(LTS)バージョンであるJava 11から本格的に普及しました。

2026年現在のLTS最新版であるJava 25(2030年9月までの標準サポート)でも当然サポートされており、今やvarは多くのプロジェクトで標準的に使われる機能です。

これからJavaを学ぶ方は、必ず押さえておきましょう。

型推論(type inference)の仕組み

型推論は、決して難しい仕組みではありません。コンパイラが、代入される値(右辺)を見て、変数の型(左辺)を「賢く推測してくれる」機能です。

例えば、以下のコードを見てみましょう。

// 従来の書き方
String message = "Hello, Java!";

// varを使った書き方
var message = "Hello, Java!";

var を使った場合、コンパイラは右辺の "Hello, Java!" が文字列リテラルであることから、変数 message の型を String であると自動的に判断します。

プログラマが明示的に String と書かなくても、コンパイル後のコードは全く同じものになるのです。

Java varとJavaScriptのvarの違い

var というキーワードから、JavaScriptを連想する方もいるかもしれません。

しかし、Javaの var とJavaScriptの var は全くの別物なので注意が必要です。

  • Javaのvar
    • 静的型付けです。一度型が決まったら、あとから別の型の値は代入できません。
    • 型推論はコンパイル時に行われます。
var message = "こんにちは"; // messageはString型に確定
message = 123; // コンパイルエラー! String型にintは代入できない
  • JavaScriptのvar
    • 動的型付けです。同じ変数に異なる型の値を再代入できます。
var message = "こんにちは"; // messageはstring型
message = 123; // エラーにならない! messageはnumber型になる

JavaとJavaScriptのvarの違いを理解しておかないと、思わぬバグの原因になります。

Javaの var は、あくまで型宣言を省略するためのシンタックスシュガー(糖衣構文)であると覚えておきましょう。

varは予約語?それとも予約型名?

意外に思われるかもしれませんが、varはJavaの予約語(keyword)ではありません。正確には「予約型名(reserved type name)」に分類されます。

そのため、以下のように変数名として var を使うこと自体はコンパイルエラーになりません。

// 変数名として使える(非推奨)
int var = 10;    // OK: varはint型変数として宣言される
// String var = "hello"; // 同一スコープでは再宣言不可(別スコープならOK)

// 型推論としても使える
var message = "Hello"; // これはローカル変数型推論

ただし、変数名にvarを使うのは可読性を著しく損なうため、実務では絶対に避けましょう。

Java Silver等の資格試験では「varは予約語か?」という出題もあるため、知識として押さえておくと安心です。

あわせて読む

注意
変数名にvarを使うのは可読性を著しく損なうため、実務では絶対に避けましょう。

Java varの基本的な使い方

Java varの基本的な使い方を示す図解

varの基本的な使い方は、宣言と同時に初期化する・nullで初期化しない・ローカル変数にのみ使うという3つのルールを守るだけです。

ここからは具体的な使い方を見ていきます。

宣言と初期化のルール

var を使うには、いくつかの重要なルールを守る必要があります。特に以下の3点は必ず押さえてください。

  • 宣言と同時に初期化が必須。varは右辺の値から型を推論するため、宣言するだけでは型が決まらず、コンパイルエラーになります。
var message; // NG! 初期化されていないため型が推論できない
message = "Hello";
  • nullでの初期化はできない。nullはどの参照型にも代入できる特殊な値です。そのため、nullだけでは具体的な型を推論できず、エラーになります。
var user = null; // NG! nullから型は推論できない
あわせて読む
  • ローカル変数にしか使えない。varが使えるのは、メソッド内やforループ内などのローカル変数に限られます。クラスのフィールド(メンバー変数)やメソッドの引数、戻り値の型としては使用できません。
あわせて読む

varはどこで使える?使える場面と使えない場面

var はどこでも使えるわけではありません。使える場面と使えない場面を、コード例と共に整理します。

【使える場面】

  • ローカル変数の宣言
public void processData() {
    var name = "Taro Yamada"; // String型
    var age = 25; // int型
    var userMap = new HashMap<Integer, String>(); // HashMap<Integer, String>型
}
var userList = List.of("Taro", "Hana", "Jiro");
for (var user : userList) {
    System.out.println(user.toUpperCase());
}
  • try-with-resources文
try (var reader = new BufferedReader(new FileReader("file.txt"))) {
    // ファイル読み込み処理
} catch (IOException e) {
    e.printStackTrace();
}

【使えない場面】

  • フィールド(インスタンス変数、クラス変数)
public class User {
    private var name = "Taro"; // NG! フィールドには使えない
}
  • メソッドの戻り値
public var getUserName() { // NG! メソッドの戻り値には使えない
    return "Taro";
}
  • メソッドの引数
public void printMessage(var message) { // NG! メソッドの引数には使えない 
    System.out.println(message);
}
  • ラムダ式(Java 10まで)Java 10では使えませんでしたが、Java 11以降はvarが使えます(詳細は後述のJEP 323セクション参照)。

配列・ジェネリクスでのvar利用例

var は、特に型名が長くなりがちなジェネリクスや配列で真価を発揮します。コードが非常にすっきりと読みやすくなるのが分かります。

  • ジェネリクスでの利用: ArrayListHashMapのような、ジェネリクスを使った複雑な型宣言がとてもシンプルになります。右辺の型定義は省略できない点に注意してください。
// 従来
Map<String, List<Map<Integer, String>>> complexData = new HashMap<>();
// varを使用
var complexData = new HashMap<String, List<Map<Integer, String>>>(); 
  • 配列での利用: 配列の宣言もvarで行えます。配列の場合も、右辺で new int[] のように型を明示する必要があります。
// 従来
int[] numbers = {1, 2, 3, 4, 5};
// varを使用
var numbers = new int[]{1, 2, 3, 4, 5}; 

IDEでvarの推論型を確認する方法

varで宣言した変数の型が分からなくなったら、IDEの機能で簡単に確認できます。

IntelliJ IDEAでは変数にカーソルを合わせるだけで推論された型がポップアップ表示されます。Eclipseでもホバーで同様に確認可能です。

コード上で型を確認したい場合は、getClass()メソッドが使えます。

var list = new ArrayList<String>();
System.out.println(list.getClass().getName()); // java.util.ArrayList

varを使ってもコンパイル後の型は明確に決まっているため、実行時にはいつでも正確な型情報を取得できます。

IDEと合わせて活用すれば、varによる型の見えにくさは十分に解消できます。

varとfinal varの組み合わせ

モダンなJava開発では、再代入しない変数にfinalを付ける習慣が推奨されています。

varfinalを組み合わせることで、型宣言を省略しつつ再代入を防止できます。

// final var: 型推論 + 再代入不可
final var maxRetry = 3;
final var userName = getUserName();

// 再代入しようとするとコンパイルエラー
// maxRetry = 5;  // NG! finalなので再代入できない

実務ではfinal varを積極的に使うのがおすすめです。変数が変更されないことが保証されるため、コードの安全性と可読性が向上します。

Java 11以降: ラムダ式の引数でvarが使える(JEP 323)

Java 11では、JEP 323によりラムダ式の引数にもvarが使えるようになりました。

通常のラムダ式と動作は同じですが、引数にアノテーションを付けたいときに便利です。

// Java 11以降: ラムダ式の引数にvarが使える
// アノテーションを付けたいときに便利
(@Nonnull var x, @Nullable var y) -> x.process(y);

// 通常のラムダと同等(型推論される)
(var x, var y) -> x + y;

// 注意: varと型名の混在は不可
// (var x, int y) -> x + y;  // NG! 全引数varか全引数省略のどちらか

ラムダ引数でvarを使う場合は、全ての引数をvarにするか、全て省略するかの二択です。varと明示的な型名を混在させるとコンパイルエラーになります。

Java varのメリットとデメリット|判断ポイント

Java varのメリットとデメリットを示す図解

varは便利な機能ですが、良い面ばかりではありません。メリットとデメリットを正しく理解し、適切に使い分けるのが重要です。

varでコードが簡潔になるメリット

最大のメリットは、コードの記述量が減り、見た目がすっきりする点にあります。

筆者のプロジェクトでは、Spring BootのService層にvarを導入した際、1メソッドあたり平均2〜3行のコード削減効果がありました。

特にDI(依存性の注入)で複数のサービスを受け取る箇所や、Stream APIの中間変数で効果が大きく、コードの見通しが明らかに改善しました。

特に、前述のジェネリクスのように型名が非常に長くなる場合、var を使うことでコードの水平方向のスペースが削減され、変数名やロジックそのものに集中しやすくなります。

// 長いクラス名やジェネリクスで効果絶大
var inputStream = new FileInputStream("data.bin");
var userRankingMap = new TreeMap<Integer, List<User>>();

// メソッドチェーンの結果を受ける場合も見やすい
var filteredUsers = userList.stream()
                            .filter(u -> u.getAge() >= 20)
                            .toList();

冗長な型宣言を省略できるため、コードの可読性が向上し、開発効率もアップします。

varで可読性が下がるケース

一方で、varの乱用はコードの可読性を著しく低下させる危険性をはらんでいます。

例えば、以下のようなコードはどうでしょうか。

var result = dataProcessor.execute();

このコードだけでは、変数resultの型がすぐに分かりません。型を知るにはexecute()メソッドの定義までジャンプしなければなりません。

コードを読む人にとって大きな負担になります。

右辺から型が自明でない場合や、ビジネスロジック上、型そのものが重要な意味を持つ場合には、var を使うべきではありません。

チーム開発での注意点

個人開発であれば自分の判断で使えますが、チームで開発を進める上では、var の使い方についてコーディング規約を設けましょう

ポイント

  • どのような場面で var の使用を許可するか
  • どのような場面では明示的な型宣言を必須とするか

こうしたルールをチームで共有しておかないと、人によって書き方がバラバラになります。結果として、コードベース全体の可読性やメンテナンス性が下がります。

var を使っても良いが、変数名で型が推測できるようにする」といった共通認識を持つだけでも、品質は大きく変わります。

varが「禁止」される現場の理由と対処法

実務では、コーディング規約でvarの使用を禁止しているプロジェクトも存在します。主な理由は以下の3つです。

  1. コードレビューの負荷増大: レビュアーが型を推測する手間が増え、見落としリスクが上がる
  2. Java 8以前のプロジェクトとの統一: チーム内でJavaバージョンが混在する場合、書き方を揃えるために禁止される
  3. 初心者が多いチームでの混乱防止: 型を意識する習慣が身についていない段階でvarを許可すると、可読性が急激に下がる

ただし、全面禁止よりも「newで型が明らかな場合のみ許可」といった部分的なルールのほうが現実的です。

CheckstyleやIntelliJ IDEAのインスペクション機能で、許可範囲外のvar使用を自動検出することもできます。

筆者の経験では、var禁止ルールは「チームの習熟度に応じて段階的に緩和する」のがベストです。

最初は右辺new時のみ許可し、慣れてきたらStream API等にも拡大する運用がスムーズでした。

Java varのベストプラクティス|使いどころ

Java varのベストプラクティスと使いどころを示す図解

java var を効果的に使いこなし、コードの品質を高めるための実践的なベストプラクティスを3つ紹介します。

適切な変数名で型を推測しやすくする

var を使う際の絶対的なルールは、変数名から型や役割が明確に推測できるように命名することです。

型情報が省略される分、変数名が持つ意味の重要性が格段に増します。

【悪い例 】

var list = getUsers(); // Listであることは分かるが、何のリストか不明
var data = findById(1); // dataの中身が全く分からない

【良い例 】

var userList = getUsers(); // ユーザーのリストであることが明確
var targetUser = findById(1); // 探している特定のユーザーだと分かる

varを使う場合は特に変数名の命名を意識しましょう。

varと明示的な型宣言の使い分け

「いつ var を使い、いつ明示的な型を使うべきか」という判断基準を持つのが重要です。

var を積極的に使うべき場面】

  • 右辺で new を使っており、型が完全に明らかな場合
var user = new User("Taro");
var idList = new ArrayList<Integer>();
  • キャストの右辺など、型が自明な場合
var user = (User) obj;
  • 中間変数を一時的に格納する場合: メソッドチェーンの途中結果など、その場でしか使わない変数には var が適しています。

【明示的な型宣言を使うべき場面】

  • 右辺から型が推測しにくい場合
// var result = getProcessingResult(); だと型が不明
ProcessingResult result = getProcessingResult();
  • インターフェース型で受けたい場合: 実装クラスではなく、より抽象的なインターフェースで変数を扱いたい場合は、明示的に型を宣言します。これはポリモーフィズムの観点からも重要です。
// ArrayListではなく、より汎用的なListとして扱いたい
// var names = new ArrayList<String>(); と書くと、namesの型はArrayListになる
List<String> names = new ArrayList<>();

筆者も過去に、varを使った変数に曖昧な名前を付けてコードレビューで指摘されたことがあります。

var data = service.execute(); と書いたところ、「dataの中身が何なのかメソッド定義を見に行かないとわからない」と。

それ以降、varを使う際は「変数名だけで型と役割が伝わるか」を自分にチェックリストとして課しています。varを使うなら、命名に3倍気を使う

これが筆者の10年間で得た実感です。

実際のプロジェクトでの活用例

実際のプロジェクトでは、Stream APIと組み合わせる場面で var が頻繁に登場します。

public List<String> getActiveUserEmails(List<User> users) {
    // Stream APIの中間操作でvarを活用
    var activeUsers = users.stream()
                           .filter(User::isActive)
                           .toList(); // activeUsersは List<User> 型

    // 別の処理...
    var userEmailMap = activeUsers.stream()
                                  .collect(Collectors.toMap(User::getId, User::getEmail));

    // さらに処理を続ける...
    var sortedEmailList = userEmailMap.values().stream()
                                      .sorted()
                                      .toList();

    return sortedEmailList;
}

複数の処理ステップに分ける際に、その都度生まれる中間的なコレクションを var で宣言すると、コードの流れが追いやすくなります。

もう一つ、Spring Bootでの実例を見てみましょう。REST APIの戻り値を受け取る場面では、varの効果が特に大きくなります。

// Before(var導入前)— 1行が非常に長くなる
ResponseEntity<List<UserProfileDto>> response = restTemplate.exchange(
    url, HttpMethod.GET, entity,
    new ParameterizedTypeReference<List<UserProfileDto>>() {});

// After(var導入後)— 型宣言が消えてすっきり
var response = restTemplate.exchange(
    url, HttpMethod.GET, entity,
    new ParameterizedTypeReference<List<UserProfileDto>>() {});

右辺のParameterizedTypeReferenceで型が明らかなため、左辺のResponseEntity<List<UserProfileDto>>は冗長です。

varを使えば、型の重複が解消されてコードが読みやすくなります。

なお、Spring Boot 4.1系(2026年8月時点の最新)でもRestClientが推奨されており、varとの相性の良さは同様です。

よくある質問

Q1. Javaのvarとは何ですか?

A1. varは、Java 10(2018年リリース)で導入されたローカル変数型推論の機能です。変数宣言時に型名を省略し、右辺の値からコンパイラが型を自動判断します。動的型付けではなく、あくまでコンパイル時に型が確定する静的型付け言語のままです。

Q2. varは予約語ですか?

A2. いいえ、varは予約語(keyword)ではなく「予約型名」に分類されます。そのため変数名としてvarという名前を使うこと自体はコンパイルエラーになりませんが、可読性を著しく損なうため実務では避けるべきです。

Q3. varは使うべきですか?

A3. 右辺から型が明らかな場合(newを使った生成時など)は積極的に使うべきです。逆に、メソッドの戻り値を受ける変数など右辺から型が推測しにくい場合は、明示的な型宣言を使うべきです。判断基準は「読み手にとって親切かどうか」です。

Q4. varを禁止しているプロジェクトがあるのはなぜですか?

A4. コードレビューの負荷増大、Java 8以前のプロジェクトとの書き方統一、初心者が多いチームでの可読性低下防止という3つの理由が主です。全面禁止よりも「型が明らかな場合のみ許可」という部分的なルールの方が現実的です。

Q5. final varとvarの違いは何ですか?

A5. final varは型推論に加えて再代入を禁止する組み合わせです。通常のvarは再代入可能ですが、final varで宣言した変数は宣言後に値を変更しようとするとコンパイルエラーになります。再代入しない変数には積極的に使うのがおすすめです。

Q6. varで宣言した変数の型はどうやって確認できますか?

A6. IntelliJ IDEAやEclipseなどのIDEでは、変数にカーソルを合わせるかホバーするだけで推論された型がポップアップ表示されます。コード上で確認したい場合はgetClass().getName()メソッドを使う方法もあります。

Q7. varはメソッドの引数や戻り値にも使えますか?

A7. いいえ、使えません。varが使えるのはローカル変数のみで、フィールド(インスタンス変数)、メソッドの引数、戻り値の型には使用できません。ただしJava 11以降はJEP 323により、ラムダ式の引数にはvarを使えます。

まとめ:Java varの使いどころと注意点

java var を使いこなし、より良いコードを目指しましょう。

varは便利だが「万能」ではない

var は、Javaのコードをより簡潔で読みやすくするための強力なツールです。特に、型名が長くなる場面では絶大な効果を発揮します。

しかし、それは「常に var を使うべき」という意味ではありません。

可読性を下げる可能性があることを常に念頭に置き、「読み手にとって親切かどうか」を基準に、明示的な型宣言と使い分けることが大切です。

初心者がつまずきやすいポイント

Javaを学び始めた方が var でつまずきやすいのは、主に以下の2点です。

ポイント

  1. 何でも入る型だと誤解してしまう: var は静的型付けであり、一度決まった型は変更できません。JavaScriptの感覚で使わないようにしましょう。
  2. 使えない場所で使おうとする: var はローカル変数専用です。フィールドやメソッドの引数・戻り値には使えないルールをしっかり覚えてください。

筆者もJavaを学び始めたころ、JavaScriptのvarと同じ感覚で「型なんて自動で決まるんでしょ」と思い込んでいた時期がありました。

フィールド変数にvarを書いてコンパイルエラー、nullで初期化してエラー……と連続で引っかかり、「型推論とはそういうものではない」と理解するまでに丸1日かかった記憶があります。

今後のJava開発での位置づけ

2026年現在、Javaは半年ごとのリリースサイクルを継続しています。

Java 26が2026年3月にリリースされ、次のJava 27は2026年9月に予定されています。

varは2018年のJava 10導入から約8年が経過し、varを前提としたコーディングスタイルはすでに多くの現場で定着しました。

今後、var を適切に使いこなすスキルは、生産性の高いJavaエンジニアにとって必須のものとなるでしょう。

ぜひあなたのプロジェクトでもvarを活用してみてください。

  • この記事を書いた人
  • 最新記事

トム

・都内自社開発企業勤務/Javaバックエンドエンジニア
/Java歴10年以上 ・首都圏在住30代
・資格:基本情報技術者/応用情報技術者/Java Silver/Python3エンジニア認定基礎 詳細なプロフィール

-Java入門