var for local variables
Apart from lambda parameters (module 37), every variable in this course has had its type written in front of its name. Since Java 10, a local variable (one declared inside a method) can be declared with var instead, and javac works out its type from the value it's given:
var name = "Ada";
var age = 36;
var height = 1.65;
var languages = new ArrayList<String>();
languages.add("Java");
System.out.println(name.length() + age + " " + height + " " + languages);
39 1.65 [Java]name is a String, age an int, height a double and languages an ArrayList<String>, exactly as if the types were written out. var isn't a type of its own, and it doesn't make Java a language where a variable can hold anything: the type is decided once, when the variable is declared, and stays.
public class Main {
public static void main(String[] args) {
var count = 0;
count = "many";
System.out.println(count);
}
}
Main.java:4: error: incompatible types: String cannot be converted to int
count = "many";
^
1 errorWhere var helps
var is at its best when the type is long and the right-hand side already shows it:
HashMap<String, ArrayList<Integer>> scores = new HashMap<String, ArrayList<Integer>>();
var scores = new HashMap<String, ArrayList<Integer>>();
Both lines declare the same variable; the second says the type once. Note that the type arguments move to the right: var scores = new HashMap<>(); would give javac nothing to work them out from, and it makes a HashMap<Object, Object>.
Where the right-hand side doesn't show the type, var makes code harder to read: in var result = calculate(data);, the reader has to look up calculate to know what result is. Many teams use var only when the type is plain to see.
Where var isn't allowed
javac must be able to work out the type from the declaration itself, so var needs a value right away, and null doesn't say which type is meant:
public class Main {
public static void main(String[] args) {
var total;
var best = null;
System.out.println("Done");
}
}
Main.java:3: error: cannot infer type for local variable total
var total;
^
(cannot use 'var' on variable without initializer)
Main.java:4: error: cannot infer type for local variable best
var best = null;
^
(variable initializer is 'null')
2 errorsvar is only for local variables (the loop variables of for included) and a lambda's parameters. Instance and static variables, method parameters and return types still need their types written out: javac answers a var there with "'var' is not allowed here".
var in loops, and a map's entries
A for-each loop's variable can be var too. That's handy for going through a map. So far, the course went through a map's keys with keySet() and looked up each value with get. A map's entrySet() gives its entries instead, each a key and its value together, with getKey() and getValue(). An entry's type is Map.Entry<String, Integer> here, a mouthful that var saves you from writing. A TreeMap, which module 31 mentioned, keeps its keys sorted, so the loop goes through them in alphabetical order:
import java.util.TreeMap;
public class Main {
public static void main(String[] args) {
var stock = new TreeMap<String, Integer>();
stock.put("water", 12);
stock.put("apple", 4);
stock.put("chips", 0);
for (var entry : stock.entrySet()) {
if (entry.getValue() == 0) {
System.out.println(entry.getKey() + ": sold out");
} else {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
}
}
}
apple: 4
chips: sold out
water: 12