自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Java新特性:數(shù)據(jù)類(lèi)型可以扔掉了?

開(kāi)發(fā) 后端
本文介紹了 var(局部類(lèi)型推斷)的使用,它可以用在局部變量、 for、 Lambda 的變量聲明中,但不能用在全局變量的聲明中,也不能用它作為方法的返回值,并且在聲明時(shí)一定要進(jìn)行初始化(也不能賦值為 null)。

在很久很久以前,我們寫(xiě)代碼時(shí)要慎重的考慮變量的數(shù)據(jù)類(lèi)型,比如下面這些:

枚舉:盡管在 JDK 5 中增加了枚舉類(lèi)型,但是 Class 文件常量池的 CONSTANT_Class_info 類(lèi)型常量并沒(méi)有發(fā)生任何語(yǔ)義變化,仍然是代表一個(gè)類(lèi)或接口的符號(hào)引用,沒(méi)有加入枚舉,也沒(méi)有增加過(guò)“CONSTANT_Enum_info”之類(lèi)的“枚舉符號(hào)引用”常量。所以使用 enum 關(guān)鍵字定義常量,盡管從 Java 語(yǔ)法上看起來(lái)與使用 class 關(guān)鍵字定義類(lèi)、使用 interface 關(guān)鍵字定義接口是同一層次的,但實(shí)際上這是由 Javac 編譯器做出來(lái)的假象,從字節(jié)碼的角度來(lái)看,枚舉僅僅是一個(gè)繼承于 java.lang.Enum、自動(dòng)生成了 values() 和 valueOf() 方法的普通 Java 類(lèi)而已,因此枚舉也歸為引用類(lèi)型了。

然而到了 JDK 10 時(shí),我們就有了新的選擇,JDK 10 中新增了 var 局部變量推斷的功能,使用它我們可以很 happy 的忘記數(shù)據(jù)類(lèi)型這件事了,那它是如何使用的呢?接下來(lái)我們一起來(lái)看。

1、使用對(duì)比

接下來(lái)我們就使用對(duì)比的方式,來(lái)體會(huì)一下 var 的作用。

場(chǎng)景一:定義字符串

舊寫(xiě)法: 

  1. String str = "Hello, Java."

新寫(xiě)法: 

  1. var s = "Hello, Java."

PS:這里的舊寫(xiě)法指的是 JDK 10 之前的版本,而新寫(xiě)法指的是 JDK 10 以后(包含 JDK 10)的版本。

場(chǎng)景二:數(shù)值相加

舊寫(xiě)法: 

  1. int num1 = 111 
  2. double num2 = 555.666d;  
  3. double num3 = num1 + num2;  
  4. System.out.println(num3); 

PS:當(dāng)遇到不同類(lèi)型相加時(shí)(int+ double)會(huì)發(fā)生數(shù)據(jù)類(lèi)型向上轉(zhuǎn)型,因此 num3 就會(huì)升級(jí)為 double 類(lèi)型。

新寫(xiě)法: 

  1. var n1 = 111L 
  2. var n2 = 555.666;  
  3. var n3 = n1 + n2;  
  4. System.out.println(n3); 

場(chǎng)景三:集合

舊寫(xiě)法: 

  1. List<Object> list = new ArrayList<>();  
  2. list.add("Hello");  
  3. list.add("Java"); 

新寫(xiě)法: 

  1. var list = new ArrayList<>();  
  2. list.add("Hello");  
  3. list.add("Java"); 

場(chǎng)景四:循環(huán)

舊寫(xiě)法: 

  1. for (Object item : list) {  
  2.     System.out.println("item:" + item);  
  3.  
  4. for (int i = 0; i < 10; i++) {  
  5.     // do something...  

新寫(xiě)法: 

  1. for (var item : list) {  
  2.     System.out.println("item:" + item);  
  3. for (var i = 0; i < 10; i++) {  
  4.     // do something...  

場(chǎng)景五:配合 Lambda 使用

舊寫(xiě)法: 

  1. List<Object> flist = list.stream().filter(v ->  
  2.                 v.equals("Java")).collect(Collectors.toList());  
  3. System.out.println(flist); 

新寫(xiě)法: 

  1. var flist = list.stream().filter(v ->  
  2.              v.equals("Java")).collect(Collectors.toList());  
  3. System.out.println(flist); 

2、優(yōu)點(diǎn)分析

通過(guò)上面的示例我們可以看出, var 具備兩個(gè)明顯的優(yōu)點(diǎn):提高了代碼的可讀性和命名對(duì)齊。

① 提高了可讀性

我們?cè)跊](méi)有使用 var 之前,如果類(lèi)型的名稱(chēng)很長(zhǎng)就會(huì)出現(xiàn)下面的這種情況: 

  1. InternationalCustomerOrderProcessor<AnonymousCustomer, SimpleOrder<Book>> orderProcessor =   
  2.     createInternationalOrderProcessor(customer, order); 

當(dāng)限定每行不能超過(guò) 150 個(gè)字符的話,變量名就會(huì)被推到下一行顯示,這樣整個(gè)代碼的可讀性就變得很低。但當(dāng)我們使用了 var 之后,代碼就變成了這樣: 

  1. var orderProcessor = createInternationalOrderProcessor(customer, order); 

從上述的代碼可以看出,當(dāng)類(lèi)型越長(zhǎng)時(shí),var(可讀性)的價(jià)值就越大。

② 命名對(duì)齊

在不使用 var 時(shí),當(dāng)遇到下面這種情況,代碼就是這樣的: 

  1. // 顯式類(lèi)型  
  2. No no = new No();  
  3. AmountIncrease<BigDecimal> more = new BigDecimalAmountIncrease();  
  4. HorizontalConnection<LinePosition, LinePosition> jumping =  
  5.   new HorizontalLinePositionConnection();  
  6. Variable variable = new Constant(6);  
  7. List<String> names = List.of("Java", "中文社群"); 

在使用了 var 之后,代碼是這樣的: 

  1. var no = new No();  
  2. var more = new BigDecimalAmountIncrease();  
  3. var jumping = new HorizontalLinePositionConnection();  
  4. var variable = new Constant(6);  
  5. var names = List.of("Java", "中文社群"); 

從上述代碼可以看出使用了 var 之后,命名對(duì)齊了,整個(gè)代碼也變得更優(yōu)雅了。

3、使用規(guī)則 & 反例

var 的實(shí)現(xiàn)來(lái)自于 JEP 286 (改善提議 286),詳情地址 :http://openjdk.java.net/jeps/286

從 JEP 286 的標(biāo)題“局部變量類(lèi)型推斷”可以看出,var 只能用于局部變量聲明,也就是說(shuō) var 必須滿(mǎn)足以下條件:

  • 它只能用于局部變量上;
  •  聲明時(shí)必須初始化;
  •  不能用作方法參數(shù)和全局變量(類(lèi)變量)。

PS:因?yàn)?var 的實(shí)現(xiàn)必須根據(jù)等會(huì)右邊的代碼進(jìn)行類(lèi)型推斷,因此它不能被賦值 null 或不被初始化。

反例一:未初始化和賦值 null

反例二:中途類(lèi)型更改

反例三:全局變量

反例四:作為返回值

4、原理分析

經(jīng)過(guò)前面的使用我們對(duì) var 已經(jīng)有了初步的認(rèn)識(shí),但 var 的實(shí)現(xiàn)原理是什么呢?

為了搞清楚它的原理,我們對(duì)下面的代碼進(jìn)行了編譯(使用命令 javac MainTest.java):

然后我們?cè)儆梅淳幾g工具打開(kāi)被編譯的類(lèi)發(fā)現(xiàn):var 竟然被替換成一個(gè)個(gè)確定的數(shù)據(jù)類(lèi)型了,如下圖所示:

由此我們可以得出結(jié)論:var 關(guān)鍵字的實(shí)現(xiàn)和它的名字密切相關(guān), var 只是局部類(lèi)型推斷,它只會(huì)在 Java 編碼期和編譯期有效,當(dāng)類(lèi)被編譯為 class 文件時(shí),var 就會(huì)變成一個(gè)個(gè)確定的數(shù)據(jù)類(lèi)型(通過(guò)推斷得出)。 所以我們可以把 var 通俗的理解為 Java 的語(yǔ)法糖,使用它可以讓我們快速優(yōu)雅的實(shí)現(xiàn)業(yè)務(wù)代碼,但 var 在字節(jié)碼層面是不存在的。

總結(jié)

本文我們介紹了 var(局部類(lèi)型推斷)的使用,它可以用在局部變量、 for、 Lambda 的變量聲明中,但不能用在全局變量的聲明中,也不能用它作為方法的返回值,并且在聲明時(shí)一定要進(jìn)行初始化(也不能賦值為 null)。使用 var 可以有效的提高代碼的可讀性和命名對(duì)齊,它的實(shí)現(xiàn)原理,是在編譯期通過(guò)等號(hào)右側(cè)的代碼進(jìn)行類(lèi)型推斷,然后再將 var 替換成確定的數(shù)據(jù)類(lèi)型。 

 

責(zé)任編輯:龐桂玉 來(lái)源: Java知音
相關(guān)推薦

2021-11-04 10:45:46

SpringBootExcelJava

2010-04-23 14:08:11

Oracle數(shù)據(jù)類(lèi)型

2010-10-15 13:28:34

MySql數(shù)據(jù)類(lèi)型

2010-09-17 14:49:04

Java數(shù)據(jù)類(lèi)型

2017-12-11 16:32:07

JavaJDK 10語(yǔ)言

2023-03-27 10:04:27

數(shù)據(jù)類(lèi)型浮點(diǎn)型布爾型

2019-08-12 11:40:48

數(shù)據(jù)庫(kù)SQLite3數(shù)據(jù)類(lèi)型

2016-08-18 14:13:55

JavaScript基本數(shù)據(jù)引用數(shù)據(jù)

2014-01-05 17:08:09

PostgreSQL數(shù)據(jù)類(lèi)型

2020-10-26 13:46:07

Java基礎(chǔ)入門(mén)篇

2022-10-27 20:42:04

JavaScripJava編程語(yǔ)言

2010-07-22 17:57:40

2021-02-22 11:51:15

Java開(kāi)發(fā)代碼

2010-08-10 17:17:59

2017-07-10 13:38:07

MySQL數(shù)據(jù)類(lèi)型整數(shù)類(lèi)型

2012-07-02 10:43:49

JVMGroovyJava

2013-07-30 14:48:58

.NET數(shù)據(jù)類(lèi)型

2013-07-30 14:00:46

.NET數(shù)據(jù)類(lèi)型

2010-09-17 14:57:34

JAVA數(shù)據(jù)類(lèi)型

2014-04-15 09:53:54

Java8類(lèi)型注解
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)