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

歡迎訪問 生活随笔!

生活随笔

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

java

王垠 java_解读王垠博客“一道 Java 面试题”

發布時間:2023/12/20 java 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 王垠 java_解读王垠博客“一道 Java 面试题” 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

偶然拜讀IT界知名大佬王垠老師的博客,發現一個有意思的題目:

1 //這段代碼里面到底哪一行錯了?為什么?2 //原文:http://www.yinwang.org/blog-cn/2020/02/13/java-type-system

3 public static voidf() {4 String[] a = new String[2];5 Object[] b =a;6 a[0] = "hi";7 b[1] = Integer.valueOf(42);8 }

雖然小菜才疏學淺,但本著學習交流的態度,寫下此篇文章來分析一下這個問題。

首先我們要讀懂每一行代碼在做什么:

String[] a = new String[2];定義一個字符串類型的數組a,并初始化。

Object[] b = a; 定義一個對象類型的數組b,并將字符串類型數組a賦值給b。

a[0] = "hi"; 使用變量a訪問數組中的第一個元素,賦值。

b[1] = Integer.valueOf(42); 使用變量b訪問數組中的第二個元素,賦值。

只有簡單的四行代碼,相信讀者都可以看的懂。

先不考慮太多,直接執行一下代碼,編譯通過,運行報錯:java.lang.ArrayStoreException: java.lang.Integer。

錯誤提示我們第四行代碼有問題,不可以將整型數據存儲到數組b中,而b是一個Object類型的數組,編譯通過,卻無法賦值。

分析一下原因,數組b的引用指向數組a,我們操作數組b,實際在內存中,訪問的應該是數組a,而數組a是一個字符串類型數組,整個過程中,并不存在Object類型的數組,僅有一個字符串類型的數組在內存中被創建,如圖:

變量a和變量b只不過是門面,通過這兩道門,到達的是同一個房間。只不過a門只允許String類型通過,而b門沒有任何限制。

因此,假如我們寫下a[0] = Integer.valueOf(42);,編譯器立刻會發現錯誤,提示類型錯誤,而b[1] = Integer.valueOf(42);的寫法是符合規則的,但由于實際數據結構是String數組,所以運行肯定無法通過。

為什么會這樣?出現這種問題的根本原因,在于Object[] b = a;,嚴格來說,這種語法是錯誤的,但是在JDK規范中卻被認可。

為什么說是錯誤的?面向對象中的繼承我們再熟悉不過了,子類完全具有父類的能力,子類可以退化成為父類。

單說String的確是Object的子類,完全符合規則,但數組是另一回事,本例中String數組僅僅能容納String類型的元素,而Object數組可以容納任意類型的元素,String數組并非完全具有Object數組的能力。

從另一個角度看,無論是String[] a還是Object[] b,這兩種寫法中的變量a和變量b,僅僅能決定指針的指向(引用哪個具體的數組),而無法控制數組內的元素,只能整體操作,而數組必然要涉及某個元素的部分操作,這就造成數組內部數據結構的“逸出”,必然會出現問題。

綜上,數組之間的抽象是錯誤的,數組之間沒有直接的繼承的能力,不屬于面向對象繼承的討論范疇。

實際編寫代碼時,不必過分糾結這個問題,盡量不使用這種危險的操作,而是用更加優雅的方式去實現:

1 //這樣就能很好的發現錯誤,避免給自己挖坑

2 public static voidf() {3 String[] a = new String[2];4 Object b = a; //數組本身也是對象

5 a[0] = "hi";6 ((String[]) b)[1] = Integer.valueOf(42);7 }

總結

以上是生活随笔為你收集整理的王垠 java_解读王垠博客“一道 Java 面试题”的全部內容,希望文章能夠幫你解決所遇到的問題。

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