Is `var` a type at runtime? Explain what 'var is not a runtime type' means and the implications.
answer
- Compile-time only; gone from the class file
- Not dynamic typing — type fixed once, never changes
- No var.class, no var[], no List<var>, no (var) cast
- Identical bytecode → zero runtime cost
- Syntactic sugar; closer to C# var / C++ auto than JS var
basics
~20 sNo. var is not a type. It is only a way to tell the compiler 'figure out the type for me.' After compilation the variable has a normal concrete type, exactly as if you had typed it yourself, so there is no var type anywhere at runtime.
solid answer
~40 s`var` exists only in source code at compile time. The compiler infers the concrete static type from the initializer and emits bytecode that uses that real type — there is no `var` in the class file, no `var` reflection type, and no runtime overhead. This means everything works as if you wrote the type explicitly: `instanceof`, `getClass()`, overloading resolution, and generics all behave identically. There is no `var.class`, you can't have a `var[]`, and you can't use `var` as a generic type argument. Because the type is fixed at the point of inference, later code is statically checked against that exact type. A useful way to summarize it: `var` is *syntactic sugar* — pure source-level convenience that disappears entirely by the time the program runs.
code
java · 12 lines// Source you write:
var names = new ArrayList<String>();
names.add("a");
// What the compiler effectively emits (var is gone):
ArrayList<String> names = new ArrayList<String>();
names.add("a");
// Proof it's just a static type:
var x = 5;
// x = "hello"; // compile error: incompatible types
System.out.println(((Object) x).getClass()); // class java.lang.Integer (boxed) — never 'var'go deeper
Knows var is not a real type and the variable has a normal concrete type after compilation; it is not dynamic typing.
Explains the compile-time/runtime split, that the type is fixed once, and that there is no runtime cost or var in bytecode.
Articulates the syntactic-sugar framing, contrasts with JS dynamic typing and with C#/C++, and notes the type-position restrictions (no var.class, var[], cast, type argument).
Can teach the concept crisply, relate it to type erasure and language-design choices, and dispel the dynamic-typing misconception across a team.
## Compile time vs runtime — the key distinction Java code goes through two phases. **Compile time** is when `javac` turns your `.java` source into `.class` bytecode. **Runtime** is when the JVM executes that bytecode. `var` lives **only** in the first phase. When the compiler sees `var x = new ArrayList<String>();`, it: 1. Reads the initializer and computes its type (`ArrayList<String>`). 2. Treats `x` from then on exactly as if you had written `ArrayList<String> x = ...`. 3. Emits bytecode that contains the real type — **the word `var` never appears in the class file.** So at runtime there is simply no such thing as a `var` type. This is what 'var is not a runtime type' means. ## Why this is sometimes confusing Developers coming from JavaScript (`var`/`let`) or scripting languages assume `var` implies dynamic typing — that the variable's type is decided as the program runs and can change. **Java is the opposite.** The type is decided once, at compile time, and is immutable for that variable. `var` is closer to C#'s `var` or C++'s `auto` than to JS's `var`. ## Concrete implications - **No runtime cost.** Identical bytecode to the explicit form; the JIT sees the same thing. Performance is unaffected. - **Reflection sees the real type.** `getClass()` / `instanceof` operate on the inferred concrete type, never on `var`. - **No `var` in type positions.** You cannot write `var.class`, `var[] arr`, `List<var>`, or `(var) obj` (a cast). `var` is only a stand-in for a local-variable's declared type. - **Overload resolution** uses the inferred type, exactly as if written out. - **It is syntactic sugar.** 'Syntactic sugar' means a source-level shorthand that the compiler expands into ordinary constructs with no new runtime semantics — `var` qualifies completely. ## A test you can do Decompile a class that uses `var` and you will see the explicit types in the bytecode — `var` is gone. That single fact captures the whole concept: it is a compile-time convenience that leaves no runtime footprint.
- How is Java's `var` different from JavaScript's `var`?JavaScript's `var` declares a dynamically typed variable whose value can be any type and change at runtime. Java's `var` is static type inference: the compiler fixes one concrete type at compile time and it never changes; it is far closer to C#'s `var` or C++'s `auto`.
- If I decompile bytecode that used `var`, what do I see?The real inferred types — `var` does not appear. It is erased into the concrete type at compile time, which proves it has no runtime existence.
saying these in an interview costs you the question
- Saying `var` implies dynamic typing like JavaScript
- Thinking the type can change at runtime
- Believing there's a runtime/performance penalty
- Trying to use `var` as a type argument, array type, or in a cast