本文主要解读下java10的Local-Variable Type Inferencehtml
@Test public void testVar(){ var list = List.of(1,2,3,4,5); var strList = list.stream() .map(e -> "hello" + e) .collect(Collectors.toList()); var result = strList.stream() .collect(Collectors.joining(",")); System.out.println(result); } @Test public void testVarInForEach(){ var data = Map.of("k1",1,"k2",2,"k3",3,"k4",4,"k5",5); for(var entry : data.entrySet()){ System.out.println(entry.getKey() + ":" + entry.getValue()); } } @Test public void testVarInTry() throws IOException { try(var input = this.getClass().getClassLoader().getResourceAsStream("demo.txt")) { int data = input.read(); while(data != -1){ System.out.print((char) data); data = input.read(); } } }
引入的var只是为了简化代码,注意var只能用于局部变量。它不能用于类成员变量,方法参数等。
引入var是一把双刃剑,一方面简化了代码,可是同时可能影响了可读性,特别是那些你不熟悉的类型。为此Stuart W. Marks给出了一份使用指南 Style Guidelines for Local Variable Type Inference in Java。其主要观点以下:
// ORIGINAL List<Customer> x = dbconn.executeQuery(query); // GOOD var custList = dbconn.executeQuery(query);
var items = new HashSet<Item>(...); // ... 100 lines of code ... items.add(MUST_BE_PROCESSED_LAST); for (var item : items) ...
var的声明与使用距离太远,不容易看清楚items的类型
// ORIGINAL ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); // GOOD var outputStream = new ByteArrayOutputStream();
好比右侧是显示类型,很是清晰
Map<String, Long> freqMap = strings.stream() .collect(groupingBy(s -> s, counting())); Optional<Map.Entry<String, Long>> maxEntryOpt = freqMap.entrySet() .stream() .max(Map.Entry.comparingByValue()); return maxEntryOpt.map(Map.Entry::getKey);
能够用var声明中间变量java
var freqMap = strings.stream() .collect(groupingBy(s -> s, counting())); var maxEntryOpt = freqMap.entrySet() .stream() .max(Map.Entry.comparingByValue()); return maxEntryOpt.map(Map.Entry::getKey);
// OK: both declare variables of type PriorityQueue<Item> PriorityQueue<Item> itemQueue = new PriorityQueue<>(); var itemQueue = new PriorityQueue<Item>(); // DANGEROUS: infers as PriorityQueue<Object> var itemQueue = new PriorityQueue<>(); // DANGEROUS: infers as List<Object> var list = List.of(); // OK: itemQueue infers as PriorityQueue<String> Comparator<String> comp = ... ; var itemQueue = new PriorityQueue<>(comp); // OK: infers as List<BigInteger> var list = List.of(BigInteger.ZERO);
// ORIGINAL boolean ready = true; char ch = '\ufffd'; long sum = 0L; String label = "wombat"; // GOOD var ready = true; var ch = '\ufffd'; var sum = 0L; var label = "wombat"; // ORIGINAL byte flags = 0; short mask = 0x7fff; long base = 17; // DANGEROUS: all infer as int var flags = 0; var mask = 0x7fff; var base = 17; // ORIGINAL float f = 1.0f; double d = 2.0; // GOOD var f = 1.0f; var d = 2.0;
var是一把双刃剑,一方面能够简化繁琐的代码,可是使用不恰当又会影响代码可读性,须要谨慎使用。ide