java 10的區域性變數型別推斷Var的用法 - foojay

發表於2021-01-06

“必須編寫供人們經常閱讀的、卻·偶然地供機器執行的程式。”-Harold Abelson

在Java 10中,新增了新功能Local-Variable Type Inference。目的是在使用初始化程式宣告區域性變數時減少樣板程式碼並提高可讀性。

讓我們通過一個例子來理解這一點。在不使用Local-Variable Type Inference的情況下編寫了以下程式碼:

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宣告來自己推斷宣告的型別。這些只是一些示例,可以幫助您理解該功能以及我們如何使用區域性變數型別推斷。

 

現在,讓我們瞭解可以在哪裡使用區域性變數型別推斷以及在哪裡不能使用區域性變數型別推斷。

可以使用的地方

  • 區域性變數初始化器
  • 增強的forloop中的索引
  • 在傳統的forloop中宣告的本地人
  • try-with-resources語句的資源變數
  • 隱式型別的lambda表示式的形式引數。(在Java 11中新增了支援)

以下程式碼段顯示了一些有效的示例:

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
}

 

無法使用的地方

  • 欄位
  • 方法引數
  • 方法返回型別
  • 區域性變數宣告,無需任何初始化
  • 不能使用null進行初始化

在下面的程式碼片段中說明如果以不支援的方式使用它將出現什麼編譯器錯誤。

//無法在沒有初始化程式的情況下推斷型別:'var'
var x;
//無法推斷型別:lambda表示式需要顯式的目標型別
var f = () -> {};
//無法推斷型別:變數初始值設定項為“ null”
var g = null;
//此處不允許使用陣列初始化程式
var k = {1, 2};

 

好處

由於此功能與可讀性相關,因此有些人會喜歡它,而有些人會討厭它。如果在程式碼檢查過程中有人說他/她不知道var的宣告型別,則意味著對他人來說不是很清楚,因此也許切換回“老式”方式來顯式宣告型別是畢竟還不錯。同樣,在某些情況下,宣告的型別非常明顯,因此您可以跳過顯式宣告的型別,而改用var。

 

相關文章