本文主要解讀下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