1. 程式人生 > 實用技巧 >03_Java 基礎_常用類

03_Java 基礎_常用類

程式碼塊

在類或方法中,使用 {} 括起來的一段程式碼,稱之為程式碼塊。

  • 區域性程式碼塊,定義在方法內部,呼叫方法時執行
  • 初始化程式碼塊,定義在類中,每建立一個物件,就會執行一次,編譯時,會把初始化程式碼塊放入構造器中
  • 靜態程式碼塊,在初始化程式碼塊前加 static,載入位元組碼時自動呼叫,只執行一次

執行程式碼時,會把工程中所有的 Java 檔案編譯成位元組碼,放到 classPath 中,當第一次使用到該類時,就把該類物件的位元組碼載入到 JVM 中

final 關鍵字

繼承的弊端:破壞了我們的封裝,它可以訪問父類中實現的細節,可以覆蓋父類中的方法。

使用 final 關鍵字修飾,表示最終的,不可修改的,保證資料安全

  • 修飾字段,不能修改,常量,必須給初始值,修飾基本資料型別表示值不能改變,修飾引用資料型別表示地址不能改變
  • 修飾方法,不能覆蓋
  • 修飾類,不能繼承

包裝類

對基本資料型別的包裝,把基本資料型別包裝成一個類,以面向物件的思想使用包裝類,使基本資料型別更強大。

基本資料型別 包裝類
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean

裝箱操作

把基本資料型別變成包裝類。

  • 使用 new 方式
  • 使用 Integer.valueOf() 方式(先找快取)

拆箱操作

把包裝類的物件,轉換為對應基本資料型別的變數

  • int num1 = num.intValue();

自動裝箱(語法糖)

可以直接把基本資料型別的值賦給包裝類物件

  • Integer i = 10;

自動拆箱(語法糖)

自動把包裝類物件轉換成基本資料型別

  • int i1 = i;

基本資料型別和包裝類

  1. 預設值

    int------------------0

    Integer-----------null

  2. 包裝類當中提供了很多方法供我們直接使用

  3. 集合框架不能存放基本資料型別(陣列可以),只能存物件

使用場景:

  • 欄位使用包裝型別(存放到堆)
  • 方法當中使用基本資料型別(存放到棧)

包裝類當中的快取設計

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

抽象方法

只定義,不實現,子類必須覆蓋。

在方法前面加一個關鍵字 abstract

特點:

  1. 沒有方法體
  2. 必須定義在抽象類或者介面當中
  3. 不能是私有的 private,不能使用 final 修飾,也不能使用 static 修飾

抽象類

  • 抽象類一般作為父類,必須要有子類實現。其實是一個不完整類。
  • 抽象類不能直接建立物件
  • 抽象類當中可以有抽象方法,也可以有非抽象方法(給子類用)
  • 子類沒有覆蓋,把子類也變成抽象方法
  • 構造方法不能定義成私有的 private,不能使用 final 修飾

命名:一般在前面加個 Abstract

介面

在 Java 中,介面表示一種規範、約束,要求實現者必須遵循該規範。用來約束使用者應該怎麼做,規範和實現相分離。

介面是一個特殊的抽象類。

介面的定義:interface 介面名稱

  • 介面沒有構造方法,不能建立物件類
  • 介面當中定義的變數,都是全域性靜態常量
  • 介面當中定義的方法,都是公共的,抽象的方法
  • 介面當中定義的內部類,都是公共的,抽象的類
  • 介面可以多繼承

介面和抽象類的區別

  • 都是被其他類繼承或實現
  • 都不能例項化
  • 都可以定義抽象方法,子類必須覆蓋
  • 介面沒有構造器,抽象類有
  • 介面只能包含抽象方法,抽象類可以包含普通方法和抽象方法
  • 介面當中成員變數 public static final,抽象類當中成員變數預設許可權
  • 介面當中方法 public abstract,抽象類當中方法預設許可權

面向介面程式設計

把實現類物件賦值給介面型別的變數

多型的好處:遮蔽了不同類之間的實現差異,達到通用程式設計

內部類

定義在類當中的類

  • 增強封裝
  • 增強程式碼維護性
  • 內部類可以直接訪問外部類成員

例項內部類

無修飾符,屬於物件,不屬於類

Outter.Inner in = out.new Inner();

外部類不能訪問內部類成員

例項內部類中有一個外部類引用,Outter.this

靜態內部類

static 修飾,屬於類,不需要建立物件

Outter.Inner in = new Outter.Inner();

靜態內部類中可以訪問外部類的靜態成員,但是沒有外部類引用

區域性內部類

定義在方法當中,不能使用修飾符,只能在定義的方法中使用,不能包含靜態變數

匿名內部類

區域性內部類的一種特殊情況,就是沒有名字的內部類,也沒有構造器,直接建立物件,只使用一次,內部方法直接執行

new 父類構造器 或 介面(){}

列舉

表示一個事物固定的狀態。是一個特殊的類,多個常量物件的集合。

  • 資料安全
  • 邏輯合理

[修飾符] enum 列舉名稱 {}

  • 列舉不能直接建立物件,私有化構造器
  • 列舉可用在 switch 中,呼叫 ordinal 序數
  • 字串轉列舉型別,web 應用中常用

常用類

Main 方法

點選執行時,JVM 會呼叫 main 方法

  • public:JVM 呼叫的方法,許可權要足夠大
  • static:Jvm 呼叫的方法,不需要建立物件,直接使用類名呼叫
  • void:Jvm 呼叫的方法,不需要任何返回值
  • main:方法名稱,必須是這個,不然 JVM 識別不了
  • String[] args:以前是指鍵盤錄入

Scanner

Scanner sc = new Scanner(System.in);
int i = sc.nextInt();

System

java.lang 包是不需要匯入的

  • System.ArrayCopy 複製陣列
  • System.currentTimeMillis 返回當前時間的毫秒值,從1970年到現在,做測試用,測試程式執行時間
  • System.exit 終止當前正在執行的 Java 虛擬機器
  • System.gc 立即執行垃圾回收器
    • finalize:當一個類被回收時呼叫此方法

Math

  • Math.random 返回一個 [0,1) 之間的隨機數
  • Math.max 返回兩個數中的最大值
  • Math.min 返回兩個數中的最小值
  • Math.sqrt 開根

BigDecimal

  • 無法準確表示高精度小數計算,尤其是金額,詳細請看 Java 基礎第一篇
  • 通常使用 String 構造器,完全可預知的
  • BigInteger 比 Long 還大的整型

String

本質是 char 型別的一個數組

  • 不可變字串,定義好不能改變,修改就會建立新的地址
    • String
      • String str = "mystr"; 是個常量物件,存在方法區中的常量池,建立一個物件或不建立
      • String str = new String("mystr"); 是個物件,在堆中開闢空間,引向常量池,至少建立一個物件
      • String str = null; 引用為空,沒有初始化,沒有分配記憶體空間
      • String str = ""; 字串為空,分配了記憶體空間,內容為空
      • == 比較記憶體地址是否相等
      • equals Object 中定義,與 == 相同,String 中覆蓋,比較內容是否相等
  • 可變字串,定義好可以改變,修改不會建立新的地址
    • StringBuilder:效率高一些
    • StringBuffer:方法前多了 synchronized,加鎖,安全一些
  • 都實現了 CharSequence 介面
  • char 型別陣列可以與 String 相互轉換
  • 返回字串長度,length
  • 獲取字串中的某個元素,charAt
  • 返回一個子字串,subString
  • 返回子字串在字串中第一次出現的位置,indexOf
  • 返回子字串在字串中最後一次出現的位置,lastIndexOf
  • 大小寫轉換,toLowerCast,toUpperCast
  • 忽略大小寫比較,equalsIgnoreCase
  • 以某一個字元對字串進行分割,split,返回字串陣列
  • 判斷開頭,startsWith
  • 去掉首尾空格,trim
  • 去掉全部空格,使用 reqlace

Random

  • new Random();
  • new Random(seed); 相同的種子生成的隨機數是一樣的
  • UUID:通用唯一識別符,結合當前時間和電腦硬體資訊生成一段字元。UUID.RandomUUID(),生成十六進位制

日期 Date

比如生日,入職時間等欄位 new Date();

日期格式化:

DateFormat.getInstance

DateFormat.getDateTimeInstance

df.format(); 日期轉字串

df.parse(); 字串轉日期

自定義日期模式:SimpleDateFormat

Date date = new Date();
SimpleDateFormat sd = new SimpleDateFormat();
String pattern = "yyyy/MM/dd HH:mm:ss";
sd.applyPattern(pattern);
System.out.println(sd.format(date));

集合

用來存放資料的一個容器

陣列和集合類的區別:

  1. 陣列當中可以存基本資料型別和引用型別
  2. 集合當中只能存放物件(引用型別),放基本資料型別也會自動裝箱
  3. 陣列長度固定,集合長度隨著元素增加而增加
  4. 如果元素個數固定使用陣列,元素個數不確定或需要增刪改查使用集合

集合類繼承體系

Collection

  • List 當中可以有重複元素,List 當中 add 方法永遠返回 true

  • Set 當中不能有重複元素,add 重複元素返回 false

  • add()

  • addAll(),新增另一個集合所有元素

  • remove()

  • removeAll(),刪除兩個集合的交集

  • contains()

  • containsAll(),是否包含傳入集合

  • retainAll(),取交集,原集合改變返回 true

  • clear()

  • isEmpty()

  • size()

  • 遍歷

    • 先把集合轉成陣列 toArray(),返回 Object 陣列

    • foreach 遍歷

    • 迭代器遍歷,裡面的物件會自動提升到 Object 型別。Iterator 是一個介面,每一個實現類都重寫了裡面的方法

      Iterator it = lsit.iterator();
      while (it.hasNext()){
          System.out.println(it.next());
      }
      
    • 迭代器遍歷時刪除,只能使用迭代器刪除,否則會報併發修改異常

    • 迭代器遍歷時新增,使用迭代器新增,List 中特有

List

有序,可重複

  • 可根據腳標新增元素,list.add(i,e)
  • 可獲取指定指令碼元素,list.get(i)
  • List 中特有的迭代器,有前一個後一個

ArrayList

陣列實現,存放資料有序、可重複。把原有的資料複製出來,再建立一個新陣列,容量增加 50%,把複製的陣列放到新陣列當中,原有的陣列丟棄。

  • 有腳標
  • 新增,依次往後移動
  • 刪除,依次往前移動
  • 查改較快,增刪較慢

LinkedList

雙向連結串列實現。

  • 往第一個位置新增(移除)元素,list.addFirst()

  • 往最後一個位置新增(移除)元素,list.addLast()

  • 也能通過腳標獲取元素,但內部實現複雜,效率較慢

  • 增刪較快,查改較慢

Vector

陣列實現。Java 1.2 後改進為可實現 List 介面,使用很少。有一些特有的方法,並且內部加鎖,執行緒安全,效率稍低。

  • add()
  • addElement()
  • elements()

陣列與集合的轉換

Arrays.asList();

list.toArray();

  • 轉過之後,不能新增刪除,其餘面向物件的方法可用
  • 開發當中不會把基本資料型別陣列轉集合,它會把整個陣列當成一個物件

Set

  • 無序,不可重複

  • 自定義物件相等判斷:不只是覆蓋 equals,還要覆蓋 hashCode

  • hashCode:與記憶體地址對應的一個編號,每一個物件都有唯一的 hashCode

HashSet

雜湊演算法實現。唯一的,無序的。

LinkedHashSet

HashSet 的子類,底層用連結串列實現。Set 集合中唯一保證元素怎麼存怎麼取。

TreeSet

二叉樹演算法實現。用來對元素進行排序。

  • 按數字大小排序
  • 按字母順序排序
  • 按 unicode 碼排序
  • 必須存放統一型別資料,否則無法排序
  • 自定義物件不能直接新增到 TreeSet 中,需實現 Comparable 介面,並覆蓋當中 compareTo 方法
  • compareTo:返回零不新增,返回正數新增到右子樹,返回負數新增到左子樹
  • 比較器:定義一個類實現 Comparator 介面,並覆蓋當中 compare 方法
  • compare:返回零不新增,返回正數新增到右子樹,返回負數新增到左子樹

Map

  • 是個介面,也叫對映關係,元素無序,維護兩個集合
  • A 集合中的每一個元素,都能在 B 集合中找到與之對應的元素
  • A 集合元素不能重複,稱為 key
  • B 集合元素可以重複,稱為 value
  • 新增 put(key,value):key 第一次新增,返回 null,key 不是第一次新增,替換 value,返回原 value
  • 清空 clear()
  • 刪除 remove(key):刪除 key-value entry
  • 長度,size(),返回 int
  • 獲取一個元素,get(key),返回 value
  • 獲取所有元素
    • 取出所有 key
    • 遍歷 key 取出 value
  • 獲取所有元素,entrySet()
  • 自定義 key 型別,覆蓋 hashCode 和 equals 方法

HashMap

典型 Map,鍵值對。

HashMap 和 HashTable 的區別:

  • 底層都是使用雜湊演算法
  • 都是雙列集合
  • HashMap 是執行緒不安全的,效率比較高
  • HashTable 是執行緒安全的,效率比較低
  • HashMap 可以存 null 值(鍵值都可以),HashTable 不能存 null 值
  • HashTable 在 Java 1.4 中被重寫,實現了 Map 介面,是個過時的類

LinkedHashMap

元素有序。

TreeMap

元素按 key 排序,排序方式參照 TreeSet。

泛型

廣泛通用的型別,程式碼模板中型別不確定,誰呼叫這段程式碼,誰就可以指明這個型別。

  1. 類的後面加上
  2. 在變數前面加上 T
  3. 建立時指明型別
  • 集合中可使用泛型,更安全
  • 泛型前後型別必須保持一致
  • Java 1.7 開始後面可以省略,菱形語法
  • 泛型沒有繼承
  • 泛型其實是個語法糖,本質還是 Object 型別,內部還是要進行強制轉換

泛型類

在類上定義了泛型,建立物件時指定

泛型方法

在方法上定義了泛型,只能用在普通方法上,不能用在靜態方法上

自定義泛型

單獨在方法上定義泛型,有引數才有意義,引數確定型別

也可在靜態方法中定義

萬用字元

不知道使用什麼型別接收時,可以用 ? 表示未知。一般只用於接收。

  • 泛型的上限,必須是指定型別或子類,? extends Type
  • 泛型的下限,必須是指定型別或父類,? super Type

泛型擦除

把一個有泛型的內容賦值給沒有泛型的內容。

異常

Java 程式在執行過程中出現的錯誤。

  • 編譯時異常:必須顯式處理,否則無法通過編譯

  • 執行時異常:RuntimeException 類及其子類,編譯時不會報錯,執行時終止程式,開發時遇到的主要異常

JVM 是怎麼處理異常的

  • main 方法收到一個異常,可以自己處理,然後繼續執行

  • 也可以交由 JVM 處理,控制檯輸出異常資訊,同時終止程式

try...catch...finally

  • catch 按順序執行
  • Java 1.7 後 catch 可以使用 | 連線捕獲多個異常
  • 只要執行了 try,finally 一定執行,除非程式終止,return 都不能阻止(先 return,再 finally)
  • finally 一般用於釋放資源,IO 操作中常見

獲取異常資訊

  • e.getMessage() //資訊,引數
  • e.toString() //類名,資訊
  • e.printStackTrace //類名,資訊,位置,從下往上看

throw 丟擲異常

  • 丟擲編譯時異常,必須要處理,或繼續往上拋直到有人(最後是 JVM)處理
  • 丟擲執行時異常,不需要處理
  • throw:定義在方法內,跟的是異常物件,只能丟擲一個異常
  • throws:定義在方法聲明後,跟的是異常類,可以丟擲多個異常

自定義異常

  • 自定義編譯時異常
    • 定義一個類繼承 Exception
    • 丟擲自己定義的異常類名
    • 要麼處理,要麼向上拋
  • 自定義執行時異常
    • 定義一個類繼承 RuntimeException
    • 丟擲自己定義的異常類名
  • 自定義帶引數異常
    • 在類當中提供一個有引數的構造方法
    • 把引數傳給父類構造方法