Java瞬息万变,随着六个月的发布周期,我们将获得可用于每个发行版的新功能。在Java 10中,添加了局部变量类型推断。它的主要目的是在使用初始化程序声明局部变量时减少样板代码并提高可读性。
必须编写程序供人们阅读,并且只能偶然地使机器执行 Harold Abelson
让我们通过一个例子来理解这一点。编写以下代码时不使用局部变量类型推断:
List<Employee> employees = Arrays.asList(new Employee(1, "Ashish", 28, 10000) , new Employee(2, "Ajay", 29, 1000) , new Employee(3, "Abhishek", 29, 10000)); Map<Integer, String> map = employees .stream() .collect(Collectors.toMap(Employee::getId, Employee::getName)); Map<Long, List<Employee>> listMap = employees .stream() .collect(Collectors.groupingBy(Employee::getSalary));
按照Java 10局部变量类型推断进行重构后:
var employees = Arrays.asList(new Employee(1, "Ashish", 28, 10000) , new Employee(2, "Ajay", 29, 1000) , new Employee(3, "Abhishek", 29, 10000)); var employeeMap = employees.stream() .collect(Collectors.toMap(Employee::getId, Employee::getName)); var groupedMap = employees.stream() .collect(Collectors.groupingBy(Employee::getSalary));
在重构的代码中,编译器可以通过查看RHS声明来自己推断声明的类型。
这些只是一些示例,可以帮助您了解功能以及我们如何使用局部变量类型推断。
现在,让我们了解在哪里可以使用局部变量类型推断,以及在哪里不能使用局部变量类型推断。
可以使用的地方:
以下代码段显示了一些有效的示例:
var str = new String("Hello"); var list = new ArrayList<String>(); var integerList = List.of(1,2,3,4); for (var data :integerList) { System.out.println(data); } for (var i = 1; i <= integerList.size(); i++) { System.out.println(i); } var path = Paths.get("/src/main/resources/app.log"); try(var file = Files.lines(path)){ //some code }
无法使用的地方:
在以下代码片段中,我解释了如果以不支持的方式使用局部变量类型推断时,将出现哪些编译器错误。
//Cannot infer type: 'var' on variable without initializer var x; //Cannot infer type: lambda expression requires an explicit target type var f = () -> {}; //Cannot infer type: variable initializer is 'null' var g = null; //Array initializer is not allowed here var k = {1, 2};
有什么好处?
如果您亲自问我,我认为开发人员应该明智地使用它。每当有功能加入时,都会感到兴奋,您肯定想尝试一下。但是,您必须了解,作为开发人员,我们阅读代码的频率要高于编写代码的频率。
由于这与可读性有关,因此有些人会喜欢它,有些人会讨厌它。因此,如果在代码审查期间有人说他们无法获得var的声明类型,那么这意味着对其他人来说不是很清楚,因此也许改回使用老式的方式声明我们的类型毕竟还不错。同样,在某些情况下,声明的类型非常明显,因此您可以跳过显式声明的类型并使用var。
原文链接:http://codingdict.com