天天看點

重學Java(二):對象無處不在

前言

本系列文章内容來自于《Thinking in Java》作者的最新續作《On Java》基礎卷,作者根據最新 Java 8、11、17的内容,重講了Java的程式設計思想,值得初學者閱讀。

操作對象

Java将一切都視為對象,但實際操作的其實是該對象的引用,再由引用來修改對象資訊。

一種安全的做法是,始終在建立引用時就進行初始化:

String s; 
String s = "asdf";      

首行代碼中,建立了一個引用,但這個引用還沒有連接配接對象,直接使用起來會有問題。

第二行代碼可以看到,字元串可以用帶引号的文本進行初始化。

建立對象

引用的作用是關聯對象。通常使用 new 關鍵字來建立對象。

資料存儲方式

  1. 寄存器。這是最快的存儲方式,因為資料會直接儲存在CPU中,但是程式員無法直接控制寄存器的配置設定,因為寄存器數量是有限的。
  2. 棧(Stack)。資料儲存在随機順序存儲器(RAM)中,處理器通過棧指針操作資料,在效率上僅次于寄存器。在棧上的所有對象都要明确其生命周期,靈活性上稍有限制。對象引用儲存在棧中。
  3. 堆(Heap)。資料也儲存在 RAM 中,用于存儲所有 Java 對象。編譯器不關心位于堆上的對象存在多久,使用較為靈活。但配置設定和清理堆存儲時花費時間略高于棧。
  4. 常量存儲區。
  5. 非 RAM 存儲。一個例子是序列化對象,指的是轉換為位元組流并能發送到其他機器上的對象;另一個例子是持久化對象,也就是儲存在磁盤上的對象,這些對象能轉換為其他形式儲存到其他媒介中,也能在需要的時候重新轉換為 RAM 對象。

注意:對基本類型來說,無需使用 new 關鍵字建立基本類型的變量,而是直接建立一個“自動變量”,也不是引用。基本類型變量會在棧上儲存它的值。

基本類型(有符号) 大小 最小值 最大值 包裝類
char 16位,2個位元組 \u0000(0) \uffff(65535) Char
byte 8位,1個位元組 -128 127 Byte
short 16位 -32768 32767 Short
int 32位 -231 231 - 1 Int
long 64位 -263 263 - 1 Long
float 32位 IEEE 754 IEEE 754 Float
double 64位 IEEE 754 IEEE 754 Double

除了以上幾個基本類型,還有

boolean

類型,其包裝類為 Boolean。通過包裝類型可以将基本類型呈現為位于堆上的非原始對象。自動裝箱和拆箱機制能夠将基本類型對象和包裝類對象自動轉換。

高精度數字

  • BigInteger:支援任意精度的整數。
  • BigDecimal:支援任意精度的浮點數

數組

建立一個用于放置對象的數組時,實際數組内包含的是引用,這些引用會被自動初始化為 null 值,即這些引用并未指向任何一個對象。操作引用前需確定其指向了某個對象。

作用域

Java對象的生命周期和基本類型有所不同。當使用new建立一個對象時,該對象在其作用域結束後依然存在,而其引用則會在作用域結束後消失。

垃圾收集器會監視所有通過new建立的對象,并及時發現哪些對象不再被引用。然後就會釋放這部分對象占用的記憶體,使這些記憶體可以用于其他新對象。垃圾回收機制解決了由于程式員忘記釋放記憶體而導緻的記憶體洩漏問題。

建立類

大多數面向對象程式設計語言會使用 class 關鍵字描述對象種類。

字段

當定義類時,可以為其定義兩種元素:字段和方法。

當一個類的字段是基本類型時,即便你沒有初始化這些字段,它們也會擁有預設值:

基本類型(有符号) 預設值
char \u0000(null)
byte (byte)0
short (short)0
int
long 0L
float 0.0f
double 0.0d
boolean false

這一特點確定了基本類型的字段一定被初始化。但這種機制并不會應用于局部變量(如在方法内部的變量),因為局部變量不是類的字段,使用前必須指派。

方法、參數和傳回值

方法最基礎的部分包括方法名、參數、傳回值以及方法體。方法名和參數清單共同構成了方法簽名。方法簽名是方法的唯一辨別符。

Java中的方法隻能作為類的一部分而存在。除static方法外,方法隻能通過對象調用。

除基本資料類型外,一般情況下,給方法參數傳遞對象,實際上就是對象的引用。

當傳回值的類型是void時,使用return關鍵字的作用是退出該方法。

編寫并運作Java程式

名稱可見性

為了清晰地描述庫的名稱,Java語言使用的方法是将網際網路域名反轉使用。因為域名是唯一的,是以不會産生沖突。

這種機制確定了所有檔案都有其對應的命名空間,同時檔案裡定義的類都有唯一對應的辨別符。但這種方式也會為源代碼管理産生挑戰。

通過空檔案夾層層嵌套而形成的這種檔案夾結構,其作用不隻是為了對應反轉的URL,通常用于儲存一些表明檔案夾内容的資料。

使用其他元件

Java消除了所謂的前向引用,即即使類稍後在檔案中才會定義,依然可以在檔案的上文中使用這個類。

import語句的作用是通知編譯器導入一個指定位置的包,即放置各種類的庫。

static 關鍵字

使用static的字段或方法不依賴于任何對象。非static的字段和方法必須基于指定的對象。不能在沒有具體對象的前提下,使用static方法直接調用非static成員或方法。

編寫程式

所有Java檔案都會導入一個特定的庫,即java.lang。裡面有一些我們不用額外導入就能使用的類,如System、String等。

Java檔案中必須存在一個與該檔案同名的類。如果需要建立一個能獨立運作的程式,檔案同名的類中還要包含一個程式啟動的入口方法 main() 方法。

main() 方法的參數是一個 String 對象的數組,用于擷取控制台的輸入。

運作程式

javac Helloworld.java   # 編譯,将.java檔案編譯成.class位元組碼檔案
java Helloworld         # 解釋,自動擷取路徑下與類名Helloworld同名的class位元組碼檔案,并運作其中的main方法      

繼續閱讀