那些年,那些坑
Java 子父類相互轉換
這個涉及到面向物件特性之多型,考驗你對這個特性理解是否徹底,接下來舉例兩個常用的 API 來解釋這個問題
子類轉父類(setContentView)

setContentView 需要一個 View 型別的引數,這裡傳入 View 的子類 TextView

這裡可以看到編譯並沒有任何問題,接下來執行一下

也是沒有問題的,證明了子類可以代替父類(子類轉父類完全OK)
父類轉子類(findViewById)

findViewById 最後返回 View 的子類,這裡我們先按常規寫法過一遍


我現在突然有一個大膽的想法

那我想強轉成 ImageView 試試看會怎麼樣

雖然 findViewById 可以強轉成 View 的子類,但是本質獲取到的還是 XML 中的那個型別 View,XML 中是 TextView,findViewById 獲取到也只能是 TextView,如果強轉成 ImageView 一定會報型別轉換異常
在這裡再總結一下,父類是可以轉成子類的,但是有一個前提條件,那就是它本質上就是這個子類的物件
基本資料型別和物件
看到這裡,你是否曾以為基本資料型別和物件一樣了?

然後事實並非如此,這裡將 int 置為空編譯不通過

基本資料型別和物件之間有很大的區別,基本資料型別只能是一個數值,而物件可以有變數和方法,int 的預設值為0,而 Integer 的預設值為 null,因為它們本身就是兩種不同的東西
switch 不止可以判斷 int
從 Java JDK 1.7 開始,switch 語句就可以開始支援判斷 string 物件 和 enum 列舉


string 中 equals 的兩種用法區別
列舉一個簡單的案例


將文字物件置為空後再次執行


丟擲了空指標異常,所以推薦第一種寫法來避免空指標異常
變數 == 物件 ?
這個也是面向物件思想的一部分,我們可以把人比作一個物件,把變數比作人的姓名,而一個人可以有多個姓名,但實際只有一個人。

要想獲得新的物件,可以使用以下三種方式
-
new
-
克隆
-
序列化
每個類其實都是 Object 的子類
我們知道 Object 類中有 equals 和 toString ,如果我們不繼承至 Object 是不是沒有這些方法了?

事實並非如此,其實我們建立一個類,什麼都不繼承,但只要它是一個類,就一定是 Object 的子類,就會擁有 Object 的屬性和方法。我說了這麼多,你還是不相信?請看下圖

泛型限定的坑
一個泛型可以限定一個繼承類和多個實現介面
你是否和我一樣,限定泛型是這樣的,然而編譯卻不給過

實際需要這樣定義泛型,並不能使用 implements

如果將介面類放在前面再試試,提示後面只能放介面類

被 final 修飾的物件
我們常常誤以為,被 final 修飾物件不能被修改,其實這種說法不是完全正確的
修改這個物件的成員變數是沒有任何問題的

但是不能對這個物件進行重新賦值

setOnClickListener(this) 的好處
在開發中,我們通常對 View 設定點選監聽是這樣子的

如果這個介面有很多個 View 要設定監聽呢?就變成了這樣

監聽一多程式碼就很亂了,我們要必須要經過一些優化

這樣的好處在於可以提高程式碼的可閱讀性,又可以複用同一個物件,達到物件優化的效果
if else 語句層級巢狀
當你看到這樣子的程式碼,都會覺得自己想靜一靜

其實這種寫法在一些老專案很常見,我們也極有為這種程式碼寫好了鋪墊,所以讓我們用規範的寫法避開這種坑吧
我們可以用 switch 語句,但是有一定侷限性(只能判斷 int,string,enum),所以當我們不能用 switch 語句的時候可以使用以下方式減少判斷語句層級巢狀

啥?這不是跟剛剛的差不多?那你可以考慮換下面這種寫法

重寫和過載分不清楚
重寫父類的 toString 方法

過載父類的 toString 方法

ListView 或 RecyclerView 使用 Glide 特別注意
錯誤的寫法:
Context context = MainActivity.this; Glide.with(context) .load(url) .into(imageView);
正確的寫法:
Glide.with(imageView.getContext()) .load(url) .into(imageView);
Glide 使用的上下文一定要是 ImageView.getContext() 的,來源於我曾經遇到過的問題,在 RecyclerView 中 itemView 中包含一個 ImageView 物件,用於載入後臺的使用者頭像 URL,但是隨著列表的滾動,ImageView 載入的圖片會混亂起來,原因是 Glide 持有 Activity 的上下文,只要 Activity 沒有 finish,Glide 就不會停止本次讀取和載入,如果使用了 ImageView 的上下文,只要 ImageView 不可見就會停止載入