日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java支持的数据类型有哪些_Java支持的数据类型有哪些?什么时候自动装拆箱?...

發布時間:2023/12/2 java 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java支持的数据类型有哪些_Java支持的数据类型有哪些?什么时候自动装拆箱?... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

java中的8種基本數據類型:boolean byte char short int float double long

自動拆裝箱的問題引入:

由于在一開始學習java的時候,”萬物皆對象“這種面向對象的看問題方式,時刻圍繞在腦海中。因為靜態的變量和基本數據類型不屬于對象,但是由8種基本數據類型的自動裝拆箱解決了基本數據類型不是對象。

在jdk1.5中引入了自動拆裝箱的新特性,在jdk1.5之前,我們想要使用integer類中的方法,我們先要把int變量變成integer類型,可以通過new Integer(intNumber) 或者調用Integer.valueOf(intNumber)方法

自動裝拆箱何時發生?

1、在調用方法時把基本數據類型作為參數,但是參數的類型是基本數據類型的包裝類時。

在學習過javaSe基礎之后,我們知道通過使用集合框架ArrayList或者Map來添加元素的時候,添加的是Object對象,在這里引入ArrayList.add()的源碼:

/**

* Appends the specified element to the end of this list.

*

* @param e element to be appended to this list

* @return true (as specified by {@link Collection#add})

*/

public boolean add(E e) {

ensureCapacity(size + 1); // Increments modCount!!

elementData[size++] = e;

return true;

}

1

2

3

4

5

6

7

8

9

10

11

對于源碼的解讀:首先我們來看看參數中的(E e),為什么是E ?而不是Object?因為E代表的是元素(集合中存儲的是元素),我們平時在泛型中可以看到 > ,T 代表的是Type 類,再比如鍵值對中的Map,K 表示的是Key,V 表示的是Value。E K V 等泛型在使用該參數之前就已經限定好了類型,如果賦值給Object的話,就不用再進行強制類型轉換了。

首先把數組的長度+1,這個操作會導致modCount加一,這個變量的作用就是記錄當前數組被操作的次數,然后直接把參數傳進來的對象賦值給上一次長度位置的元素。返回true表示添加成功

當我們調用ArrayList.add()方法的時候,可以直接調用

ArrayList arrayList = new ArrayList();

arrayList.add(10);

1

2

我們反編譯這段代碼:

public class AutoboxingTest

{

public AutoboxingTest()

{

}

public static void main(String args[])

{

ArrayList arrayList = new ArrayList();

arrayList.add(Integer.valueOf(100));

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

可以看到,編譯器在編譯的時候,檢測到arrayList.add()需要的是Integer對象,所以把int類型自動裝箱成Integer類型。

2、 給基本數據類型的包裝類賦值為基本數據類型的時候。

我們還是以Integer和int類型的變量作為例子:

public class AutoboxingTest2 {

public static void main(String[] args) {

Integer integer = 10;

}

}

1

2

3

4

5

6

7

繼續反編譯例子:

public class AutoboxingTest2

{

public AutoboxingTest2()

{

}

public static void main(String args[])

{

Integer integer = Integer.valueOf(10);

}

}

1

2

3

4

5

6

7

8

9

10

11

12

什么時候自動裝箱不起作用?

當我們要調用的方法中存在重載的時候,即基本類型數據作為唯一參數的方法與該基本類型包裝類作為唯一參數的方法重載,這時候自動裝箱不起作用。

例子:

public class InvalidateAutoboxing {

public void print(int num) {

System.out.println("i am int !");

}

public void print(Integer num) {

System.out.println("i am integer!");

}

}

public class InvalidateAutoboxingTest {

public static void main(String[] args) {

InvalidateAutoboxing invalidateAutoboxing = new InvalidateAutoboxing();

invalidateAutoboxing.print(5);

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

運行結果:

這里寫圖片描述

使用自動裝箱拆箱需要注意的地方:

1、循環與自動裝箱拆箱

public class CirculateAndAutoboxingAndAutounboxing {

public static void main(String[] args) {

Integer sum = 0;

for (int i = 0; i < 200; i++) {

sum += i;

}

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

反編譯:

public class CirculateAndAutoboxingAndAutounboxing

{

public CirculateAndAutoboxingAndAutounboxing()

{

}

public static void main(String args[])

{

Integer sum = Integer.valueOf(0);

for(int i = 0; i < 200; i++)

sum = Integer.valueOf(sum.intValue() + i);

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

反編譯代碼解讀:由于sum是Integer類型,但是sum+=i 需要sum先自動拆箱成int類型(調用intValue()方法),進行相加之后,再自動裝箱成Integer類型把結果賦給sum。

Integer.valueOf源碼解析:

/**

* Returns a Integer instance representing the specified

* int value.

* If a new Integer instance is not required, this method

* should generally be used in preference to the constructor

* Integer(int), as this method is likely to yield

* significantly better space and time performance by caching

* frequently requested values.

*

* @param i an int value.

* @return a Integer instance representing i.

* @since 1.5

*/

public static Integer valueOf(int i) {

final int offset = 128;

if (i >= -128 && i <= 127) { // must cache

return IntegerCache.cache[i + offset];

}

return new Integer(i);

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

首先我們在源碼說明中看到了該構造器緩存經常使用的數據以減少內存的使用和提高效率,Integer把緩沖區的上限腳標設置成128,如果傳進來的數據i在-128~127之中,直接返回緩沖區中的IntegerCache.cache[i + 128] 位中的元素

IntegerCache的源碼解讀:

private static class IntegerCache {

private IntegerCache(){}

static final Integer cache[] = new Integer[-(-128) + 127 + 1];

static {

for(int i = 0; i < cache.length; i++)

cache[i] = new Integer(i - 128);

}

}

1

2

3

4

5

6

7

8

9

10

IntegerCache是Integer的內部類,并且內部數組的上限為256元素,在這個內部類中使用了靜態代碼塊(在類加載的時只執行一次),把-128~127都緩存在數組中。所以以后調用的時候就可以直接返回Integer對象,而不用return new Integer(i); Integer Short Long的緩沖數組是一樣的,但是Character的范圍為0~127,Double和Float沒有緩沖數組

話又說回來,剛剛我們在分析循環與自動裝拆箱的使用需要注意:當參與的數值不在緩存的范圍內,會產生大量的對象,這樣會產生很多垃圾對象,增加GC的工作壓力。

2、自動裝拆箱與三元運算符造成的空指針異常(NPE)

public class AutounboxingWithConditionalOperator {

public static void main(String[] args) {

HashMap hashMap = new HashMap();

Boolean b = (hashMap != null ? hashMap.get("test") : false);

}

}

1

2

3

4

5

6

7

8

9

10

運行:

這里寫圖片描述

發生了空指針異常

如果在Map中添加了test這條數據:

public class AutounboxingWithConditionalOperator {

public static void main(String[] args) {

HashMap hashMap = new HashMap();

hashMap.put("test", true);

Boolean b = (hashMap != null ? hashMap.get("test") : false);

System.out.println(b);

}

}

1

2

3

4

5

6

7

8

9

10

運行:

這里寫圖片描述

我們再反編譯剛剛NPE異常的代碼:

public class AutounboxingWithConditionalOperator

{

public AutounboxingWithConditionalOperator()

{

}

public static void main(String args[])

{

HashMap hashMap = new HashMap();

Boolean b = Boolean.valueOf(hashMap == null ? false : ((Boolean)hashMap.get("test")).booleanValue());

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

下面是hashMap.get(key)方法的說明:

Returns the value to which the specified key is mapped,

*or null if this map contains no mapping for the key.

由上面可以看出,由于Map.get(key)方法,如果沒有指定的數據,返回的是null。

再由于三元運算符有如下定義:

The type of a conditional expression is determined as follows:

1、If the second and third operands have the same type (which may be the null type), then that is the type of the conditional expression.

2、If one of the second and third operands is of primitive type T, and the type of the other is the result of applying boxing conversion (§5.1.7) to T, then the type of the conditional expression is T.

3、If one of the second and third operands is of the null type and the type of the other is a reference type, then the type of the conditional expression is that reference type.

譯文:

三元運算符的類型由以下情況決定:

1、如果第二和第三個操作結果擁有同樣類型(這個類型可能為null),那么這個類型就是該三元運算符的結果類型

2、如果第二個操作和第三個操作結果其中一個的結果類型為基本數據類型,另外一個操作結果為可以裝箱轉換成與前面一種類型一致的包裝類,那么這個三元運算符的運算結果類型為基本數據類型,即把包裝類拆裝。

3、如果在第二、三個操作結果中,有一個為null類型,另外一個為引用類型,那么這個三元運算符的表達式為引用類型。

綜上所述,對于上面出現的情況,對于一個操作結果為基本類型,另外一個為包裝類型的三元運算符表達式來說,為了避免NEP的產生,可以通過把它們變成同樣類型(參考三元運算符定義的第一條)。

參考資料:

Conditional Operator ? :

Boxing Conversion

The Java? Tutorials about Autoboxing and Unboxing

What is Autoboxing and Unboxing in Java

Java中的自動裝箱與拆箱

要裝箱還是拆封

4.2 自動裝箱、拆箱

Java 自動裝箱和拆箱

Java泛型中K T V E ? object等的含義

自動拆箱導致空指針異常

總結

以上是生活随笔為你收集整理的java支持的数据类型有哪些_Java支持的数据类型有哪些?什么时候自动装拆箱?...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。