1.Java程序設(shè)計概述
- 1)簡單性
Java沒有頭文件欢策、指針運(yùn)算柠横、結(jié)構(gòu)、聯(lián)合平匈、操作符重載框沟、虛基類等。 - 2)面向?qū)ο?br> Java沒有多重繼承增炭,取而代之的是更簡單的接口概念忍燥。Java提供了更豐富的運(yùn)行時自省功能。
- 3)分布式
Java有一個豐富的例程庫隙姿,用于處理HTTP和FTP之類的TCP/IP協(xié)議梅垄。 - 4)健壯性
Java采用的指針模型可以消除重寫內(nèi)存和損壞數(shù)據(jù)的可能性。 - 5)安全性
Java適用于網(wǎng)絡(luò)/分布式環(huán)境输玷。Java防范各種攻擊:
運(yùn)行時堆棧溢出队丝;
破壞自己的進(jìn)程空間外的內(nèi)存;
未經(jīng)授權(quán)讀寫文件欲鹏。 - 6)體系結(jié)構(gòu)中立
Java編譯器生成與特定的計算機(jī)體系結(jié)構(gòu)無關(guān)的字節(jié)碼指令机久,可以在任何機(jī)器上解釋執(zhí)行,也可以動態(tài)地翻譯成本地機(jī)器代碼赔嚎。 - 7)可移植性
Java規(guī)范中沒有“依賴具體實現(xiàn)”的地方膘盖。基本數(shù)據(jù)類型的大小以及有關(guān)運(yùn)算都做了明確的說明尤误。
除了與用戶界面有關(guān)的部件外侠畔,所有其他Java庫都能很好地支持平臺獨(dú)立性。包括文件损晤、正則表達(dá)式软棺、XML、日期和時間尤勋、數(shù)據(jù)庫喘落、網(wǎng)絡(luò)連接德崭、線程等,而不用關(guān)心底層操作系統(tǒng)揖盘。 - 8)解釋型
- 9)高性能
字節(jié)碼可以在運(yùn)行時刻動態(tài)地翻譯成對應(yīng)運(yùn)行這個應(yīng)用的特定CPU的機(jī)器碼。
即時編譯器的優(yōu)勢:可以監(jiān)控經(jīng)常執(zhí)行哪些代碼并優(yōu)化這些代碼以提高速度锌奴。更為復(fù)雜的優(yōu)化是函數(shù)調(diào)用(內(nèi)聯(lián))兽狭。必要時,還可以撤銷優(yōu)化鹿蜀。 - 10)多線程
- 11)動態(tài)性
當(dāng)需要將某些代碼添加到正在運(yùn)行的程序中時箕慧,動態(tài)性將是一個非常重要的特性。
- 用戶從Internet下載Java字節(jié)碼茴恰,并在自己的機(jī)器上運(yùn)行颠焦。在網(wǎng)頁運(yùn)行的Java程序稱為applet。
2.Java程序設(shè)計環(huán)境
-
java術(shù)語
JRE——包含虛擬機(jī)往枣,但不包含編譯器伐庭。
- Windows和Linux上安裝JDK時,需要將jdk/bin目錄加入到執(zhí)行路徑中——執(zhí)行路徑是操作系統(tǒng)查找可執(zhí)行文件時所遍歷的目錄列表
- C:\Program Files\Java\jdk-10\lib\src.zip文件中包含了所有公共類庫的源代碼分冈。新建一個目錄javasrc圾另,將其解壓到這個新目錄。
更多的源代碼雕沉,例如編譯器集乔、虛擬機(jī)、本地方法以及私有輔助類坡椒,訪問http://jdk.java.net/10/扰路。 - javadoc的安裝
javadoc的下載路徑 - 使用Windows命名行工具
javac是一個java編譯器,將文件Welcome.java編譯成Welcome.class倔叼。java啟動Java虛擬機(jī)汗唱,虛擬機(jī)執(zhí)行編譯器放在class文件中的字節(jié)碼。
有關(guān)問題可以查看java在線文檔缀雳。
E:
cd E:\IdeaProjects\corejava\v1ch02\Welcome
dir //查看當(dāng)前目錄有哪些文件
javac Welcome.java //編譯器編譯成字節(jié)碼
java Welcome //虛擬機(jī)執(zhí)行字節(jié)碼
cd .. //返回到上一級目錄
cd ImageViewer // 可以使用Tab鍵補(bǔ)全
javac ImageViewer.java
java ImageViewer
- Java區(qū)分大小寫
3.Java的基本程序設(shè)計結(jié)構(gòu)
- 源代碼的文件名必須與公共類的名字相同渡嚣,并用.java作為擴(kuò)展名。
- java ClassName
運(yùn)行已編譯的程序時肥印,Java虛擬機(jī)將從指定類中的main方法開始執(zhí)行识椰。
public class ClassName
{
public static void main(String[] args)
{
program statements
}
}
- Java中所有函數(shù)都屬于某個類的方法,因此深碱,main方法必須有一個外殼類腹鹉,并且main方法必須是靜態(tài)的。main方法沒有為操作系統(tǒng)返回“退出代碼”敷硅。
- Java使用的通用語法:
object.method(parameters)
- 注釋
// /* /
/* */ 這種注釋可以用來自動生成文檔功咒。
-
數(shù)據(jù)類型
1)四種整型
Java沒有任何無符號形式的int long short byte類型
2)兩種浮點(diǎn)型
Double.POSITIVE_INFINITY正無窮大
Double.NEGATIVE_INFINITY負(fù)無窮大
Double.NaN(不是一個數(shù)字)
3)表示Unicode編碼的字符單元的字符類型char
轉(zhuǎn)義序列\(zhòng)u0000到\uffff
特殊字符的轉(zhuǎn)義序列:
在Java中愉阎,char類型描述了UTF-16編碼中的一個代碼單元,強(qiáng)烈建議不要在程序中使用char類型力奋,除非確實需要處理UTF-16代碼單元榜旦。
4)表示真值的boolean
false和true,整型值和布爾值之間不能進(jìn)行轉(zhuǎn)換景殷。這個跟C++不一樣溅呢,因此會避免因為轉(zhuǎn)換而帶來的麻煩。
if (Double.isNaN(x)) //檢查x是否不是一個數(shù)字
- final指示常量
static final設(shè)置一個類常量猿挚,可以在一個類中的多個方法中使用咐旧。
- Math類中的sqrt方法處理的不是對象,這樣的方法被稱為靜態(tài)方法绩蜻。
>>>運(yùn)算符會用0填充高位铣墨,>>用符號位填充高位。不存在<<<運(yùn)算符办绝。
移位運(yùn)算符的右操作數(shù)要完成模32的運(yùn)算伊约。1 << 35等價于 1 << 3.
- Java字符串是Unicode字符序列,Java沒有內(nèi)置的字符串類型八秃,由標(biāo)準(zhǔn)類庫中的String提供碱妆。
Java API查詢
任何一個Java對象都可以轉(zhuǎn)換成字符串。
String類對象稱為不可變字符串昔驱。不可變字符串雖然修改(需要重新創(chuàng)建)慢疹尾,但是可以讓字符串共享。
equals方法檢測兩個字符串是否相等骤肛;==只能確定兩個字符串是否放置在同一位置上纳本。
Java字符串由char值序列組成。大多數(shù)常用的Unicode字符使用一個代碼單元就可以表示腋颠,而輔助字符需要一對代碼單元表示繁成。length方法返回采用UTF-16編碼表示的給定字符串所需的代碼單元數(shù)量。要想得到實際的長度淑玫,即碼點(diǎn)數(shù)量巾腕,可以使用codePointCount.
遍歷字符串,查看每一個碼點(diǎn)(不要使用char絮蒿,這個是查看代碼單元)如下尊搬,另一種方法是使用codePoints
//方法1
int cp = sentence.codePointAt(i);
if (Character.isSupplementaryCodePoint(cp)) i += 2;
else i++;
//方法2
int[] codePoints = str.codePoints().toArray();
//將碼點(diǎn)數(shù)組轉(zhuǎn)換為一個字符串
String str = new String(codePoints, 0, codePoints.length);
- 構(gòu)建字符串
采用字符串連接的方式效率比較低,每次連接字符串土涝,都會構(gòu)建一個新的String對象佛寿,既耗時,又浪費(fèi)空間但壮。
StringBuilder類可以避免這個問題冀泻。
StringBuilder builder = new StringBuilder();
builder.append(ch);
builder.append(str);
String completedString = builder.toString();
-
標(biāo)準(zhǔn)輸入輸出
Scanner類定義在java.util包中常侣。
當(dāng)使用的類不是定義在基本java.lang包中,一定要使用import指示將相應(yīng)的包加載進(jìn)來弹渔。
關(guān)于時間的格式化選項胳施,在新代碼中,應(yīng)該使用java.time包方法肢专。
//輸入
import java.util.*;
Scanner in = new Scanner(System.in);
String name = in.nextLine();
//格式化輸出
System.out.printf("Hello, %s. Next year, you'll be %d", name, age);
- 文件輸入輸出
//讀取
Scanner int = new Scanner(Paths.get("C:\\mydirectory\\myfile.txt"), "UTF-8");
//寫入
PrintWriter out = new PrinterWriter("myfile.txt", "UTF-8"); //文件位于java虛擬機(jī)啟動路徑的相對位置
- 不能在嵌套的兩個塊中聲明同名的變量巾乳。與C++不同。
在循環(huán)中鸟召,檢測兩個浮點(diǎn)數(shù)是否相等需要格外小心,由于舍入誤差氨鹏,最終可能得不到精確值欧募,因此永遠(yuǎn)不會結(jié)束。
Java提供一種帶標(biāo)簽的break語句仆抵,類似于C++ goto跟继。
- 大數(shù)值
如果基本的整數(shù)和浮點(diǎn)數(shù)精度不能夠滿足需求,可以使用java.math包中的兩個很有用的類:BigInteger和BigDecimal镣丑√蛱牵可以處理包含任意長度數(shù)字序列的數(shù)值。BigInteger實現(xiàn)了任意精度的整數(shù)運(yùn)算莺匠,BigDecimal實現(xiàn)了任意精度的浮點(diǎn)數(shù)運(yùn)算金吗。
Java沒有提供運(yùn)算符重載的功能。
- 數(shù)組
數(shù)組長度不要求是常量趣竣;
越界訪問數(shù)組后面的元素會引發(fā)異常而終止執(zhí)行摇庙;
一旦創(chuàng)建了數(shù)組,就不能再改變大小遥缕。
int[] a = new int[100];
// for each循環(huán)
for (variable: collection) statement
//更賤大的打印數(shù)組中所有值的方法
System.out.println(Arrays.toString(a));
- Java數(shù)組與C++分配在堆上的數(shù)組指針一樣卫袒,[]運(yùn)算符被預(yù)定義為檢查數(shù)組邊界,沒有指針運(yùn)算单匣。
- 在Java應(yīng)用程序的main方法中夕凝,程序名并沒有存儲在args數(shù)組中
java Message -h world
args[0] 是"-h"。
- 對數(shù)組的一些操作可以使用java.util.Arrays
- Java的多維數(shù)組被解釋為“數(shù)組的數(shù)組”户秤,Java只有一維數(shù)組码秉。可以創(chuàng)建一個不規(guī)則數(shù)組虎忌,每一個子數(shù)組元素不一樣多泡徙。
4.對象與類
- 在Java中,所有類都源自O(shè)bject
- 對象的三個主要特性
1)行為
2)狀態(tài)
3)標(biāo)識 - OOP程序設(shè)計:首先從設(shè)計類開始膜蠢,然后再往每個類中添加方法堪藐。
識別類的簡單規(guī)則是在分析問題的過程中尋找名詞莉兰,而方法對應(yīng)著動詞。 -
類之間的關(guān)系
1)依賴("uses-a")
如果一個類的方法操縱另一個類的對象礁竞,就說一個類依賴于另一個類糖荒。
應(yīng)該盡可能將相互依賴的類減至最少。
2)聚合("has-a")
3)繼承("is-a")
- Math類只封裝了功能模捂,它不需要也不必隱藏數(shù)據(jù)捶朵。
- 一個對象變量并沒有實際包含一個對象,而僅僅引用一個對象狂男。
可以將Java對象變量看作C++對象指針综看。
所有Java對象都存儲在堆中。
Date deadline;//沒有指向任何對象岖食,不能使用
deadline = new Date(); //可以使用
- 要想創(chuàng)建一個完整的程序红碑,應(yīng)該將若干類組合在一起,其中只有一個類有main方法泡垃。
- 可以認(rèn)為Java編譯器內(nèi)置了make功能
- 構(gòu)造器總是伴隨著new操作符的執(zhí)行被調(diào)用析珊。
- 在Java中,所有的方法都必須在類的內(nèi)部定義蔑穴。是否將某個方法設(shè)置為內(nèi)聯(lián)方法是Java虛擬機(jī)的任務(wù)忠寻。
- 封裝的優(yōu)點(diǎn)
1)可以改變內(nèi)部實現(xiàn),除了該類的方法之外存和,不會影響其他代碼
2)更改器可以執(zhí)行錯誤檢查奕剃,然而直接對域進(jìn)行賦值將不會進(jìn)行這些處理 - 注意不要編寫返回引用可變對象的訪問器方法。如果需要返回一個可變對象的引用捐腿,應(yīng)該首先對它進(jìn)行克隆祭饭。
- final修飾可變的類,有點(diǎn)類似于頂層const叙量,表示final變量中的對象引用不能再指向其他的對象倡蝙,但是這個對象中的內(nèi)容可以更改。
final修飾大都用于基本類型域或不可變類的域绞佩。(String類就是不可變的類寺鸥。)表示在后面的操作中,不能夠再對它進(jìn)行修改品山。
- 可以認(rèn)為靜態(tài)方法是沒有this參數(shù)的方法胆建。靜態(tài)方法不能操作對象,不能訪問實例域肘交。但是可以訪問自身類中的靜態(tài)域笆载。
在下面兩種情況下使用靜態(tài)方法:
1)一個方法不需要訪問對象狀態(tài),其所需參數(shù)都是通過顯式參數(shù)提供(如Math.pow)
2)一個方法只需要訪問類的靜態(tài)域 - main是靜態(tài)的。在啟動程序時還沒有任何一個對象凉驻,靜態(tài)的main方法將執(zhí)行并創(chuàng)建程序所需要的對象腻要。
每一個類可以有一個main方法。這是一個常用于對類進(jìn)行單元測試的技巧涝登。
獨(dú)立測試類:java classname
測試整個程序(類屬于這個程序):java Application
- Java總是采用按值調(diào)用雄家。
- 方法參數(shù)有兩種類型
1)基本數(shù)據(jù)類型(數(shù)字、布爾值)
2)對象引用
如下swap函數(shù)并不能實現(xiàn)對象的交換胀滚,在C++中要實現(xiàn)該交換趟济,不能只交換指針,而是要交換指針?biāo)赶虻膬?nèi)容咽笼。C++也有引用交換顷编,實際上交換的也是內(nèi)容。
//該函數(shù)并不能實現(xiàn)對象的交換
public static void swap(Employee x, Employee y) { //x y都是對象引用
Employee temp = x;
x = y;
y = temp;
}
- 方法的簽名signature——方法名+參數(shù)類型剑刑。返回類型不是方法簽名的一部分勾效。Java基于簽名進(jìn)行重載。Java重載和C++重載一樣叛甫,都是基于簽名進(jìn)行重載。
- 僅當(dāng)類沒有提供任何構(gòu)造器的時候杨伙,系統(tǒng)才會提供一個默認(rèn)的構(gòu)造器其监。
- C++ 11規(guī)定,可以為數(shù)據(jù)成員提供一個類內(nèi)初始值限匣。沒有初始值的成員將被默認(rèn)初始化抖苦。這個跟Java的顯式域初始化是一致的。
- Java通常使用a+實例域作為參數(shù)米死;或者直接this.name = name使用this的形式锌历。
C++使用m或x。
- 三種初始化數(shù)據(jù)域的方法
1)在構(gòu)造器中設(shè)置值
2)在聲明中賦值
3)初始化塊
首先運(yùn)行初始化塊峦筒,然后運(yùn)行構(gòu)造器的主體部分究西。
- 由于有自動垃圾回收器,所以Java不支持析構(gòu)器物喷。
但是卤材,當(dāng)對象使用了內(nèi)存之外的其他資源,比如文件峦失,或使用了系統(tǒng)資源的另一個對象句柄扇丛。這時將其回收和再利用將顯得十分重要。
可以添加一個finalize方法尉辑,該方法將在垃圾回收器清除對象之前調(diào)用帆精。
- 所有標(biāo)準(zhǔn)的Java包都處于java和javax包層次中。
使用包的主要原因是確保類名的唯一性。 - 有兩種方式訪問另一個包中的公有類
1)在每個類名之前添加完整的包名
2)使用import語句(類似于C++的namespace和using)
import語句是一種引用包含在包中的類的簡明描述卓练。一旦使用了import語句隘蝎,就不必寫出包的全名。
如果兩個包中有相同名字的類昆庇,再增加一個特定的import語句來表明使用哪個類末贾。如果兩個Date類都需要,則使用完整的包名即可整吆。
java.time.LocalDate today = java.time.LocalDate.now();
import java.util.*;
import java.sql.*;
import java.util.Date; //sql中也有Date類
- import還可以導(dǎo)入靜態(tài)方法和靜態(tài)域的功能
import static java.lang.System.*; //導(dǎo)入類System的靜態(tài)方法和靜態(tài)域
- 將類放入包中的方法
在源文件的開頭拱撵,定義類代碼之前,加入包的名字表蝙。
如果沒有package語句拴测,會放在一個默認(rèn)包中。
將包中的文件放到與完整的包名匹配的子目錄中府蛇。com.horstmann.corejava包中所有源文件放在com/horstmann/corejava集索。
注意:編譯器在編譯源文件的時候不檢查目錄結(jié)構(gòu)。但是如果包與目錄不匹配汇跨,虛擬機(jī)就找不到類务荆。
package com.horstmann.corejava;
public class Employee;
{
...
}
- 沒有指定public和private,這個部分(類穷遂、方法或變量)可以被同一個包中的所有方法訪問函匕。(這個默認(rèn)的范圍有點(diǎn)大)
- 類加載器明確禁止加載用戶自定義的、包名以“java.”開始的類蚪黑。
并且可以通過包密封機(jī)制來解決將各種包混在在一起的問題盅惜。如果將一個包密封起來,就不能再向這個包添加類了忌穿。
-
類路徑
為了使類能夠被多個程序共享抒寂,需要做到以下幾點(diǎn):
如下,類路徑包括:
1)基目錄/home/user/classdir或c:\classes;
2)當(dāng)前目錄(.)掠剑;
3)JAR文件/home/user/archives/archive.jar后c:\archives\archive.jar
運(yùn)行時庫文件(rt.jar和在jre/lib與jre/lib/ext目錄下的一些其他的JAR文件)會被自動搜索屈芜,不必將它們顯式地列在類路徑中。
javac編譯器總是在當(dāng)前的目錄中查找文件朴译,但Java虛擬機(jī)僅在類路徑中有"."目錄的時候才查看當(dāng)前目錄沸伏。
//UNIX
java -classpath /home/user/classdir:.:/home/user/archives/archive.jar
//Windows
java -classpath c:\classdir;.;c:\archives\archive.jar
虛擬機(jī)查詢的過程:
假定要查找com.horstmann.corejava.Employee類
1)jre/lib和jre/lib/ext目錄下
2)/home/user/classdir/com/horstmann/corejava/Employee.class
3)com/horstmann/corejava/Employee.class從當(dāng)前目錄開始
4)com/horstmann/corejava/Employee.class inside /home/user/archives/archive.jar編譯器查詢的過程
假定源文件包含
import java.util.;
import com.hortstmann.corejava.;
并且源代碼引用了Employee類。
1)查找java.lang.Employee(默認(rèn)導(dǎo)入的lang包)
2)java.util.Employee
3)com.horstmann.corejava.Employee
4)當(dāng)前包中的Employee
5)編譯器還要查看源文件是否比類文件新动分。如果是毅糟,則源文件就會被自動得重新編譯。
- javadoc可以由源文件生成一個HTML文檔澜公。
- 類設(shè)計技巧
1)一定要保證數(shù)據(jù)私有
2)一定要對數(shù)據(jù)初始化
3)不要在類中使用過多的基本類型
4)不是所有的域都需要獨(dú)立的域訪問器和域更改器
5)將職責(zé)過多的類進(jìn)行分解
6)類名和方法名要能夠體現(xiàn)它們的職責(zé)
7)優(yōu)先使用不可變的類
5.繼承
- Java中所有的繼承都是公有繼承
- 子類覆蓋超類方法的注意點(diǎn)
1)不能直接訪問超類的私有域
2)調(diào)用超類的訪問器時姆另,加上super.
public class Manager extends Employee
{
public double getSalary()
{
double baseSalary = super.getSalary();
return baseSalary + bonus;
}
}
- 子類構(gòu)造器
使用super調(diào)用超類構(gòu)造器必須是子類構(gòu)造器的第一條語句喇肋。如果子類的構(gòu)造器沒有顯式地調(diào)用超類的構(gòu)造器,則將自動地調(diào)用超類默認(rèn)(沒有參數(shù))的構(gòu)造器迹辐。 - 在Java中蝶防,不需要將方法聲明為虛擬方法,動態(tài)綁定是默認(rèn)的處理方式明吩。如果不希望一個方法具有虛擬特征间学,可以將其標(biāo)記為final。
- 由一個公共超類派生出來的所有類的集合稱為繼承層次印荔。
- "is-a"規(guī)則低葫,表明子類的每個對象也是超類的對象。
另一種表述法是置換法則仍律。表明程序中出現(xiàn)超類對象的任何地方都可以用子類置換嘿悬。
Java中,對象變量是多態(tài)的水泉。一個Employee變量既可以引用一個Employee類對象善涨,也可以引用一個Employee類的任何一個子類的對象。 - 同C++一樣草则,反過來賦值不可以钢拧,且超類引用子類對象時,不能調(diào)用子類特有的方法炕横,這是由聲明類型決定的源内。
- 一個超類數(shù)組和一個子類數(shù)組同時引用同一個子類對象,此時對超類存儲超類引用看锉,應(yīng)該引發(fā)錯誤
Manager[] managers = new Manager[10];
Employeep[ staff = managers;
staff[0] = new Employee(...); //引發(fā)ArrayStoreException異常
- 理解方法調(diào)用
1)獲取所有候選方法
包括重載的超類中同名的屬性為public的方法
2)進(jìn)行參數(shù)類型匹配
3)如果是private、static塔鳍、final方法或構(gòu)造器伯铣,編譯器靜態(tài)綁定。如果依賴于隱式參數(shù)的實際類型轮纫,則在運(yùn)行時實現(xiàn)動態(tài)綁定 - 每次都搜索的開銷太大腔寡。虛擬機(jī)為每個類創(chuàng)建了一個方法表,列出了所有方法的簽名和實際調(diào)用的方法掌唾。
此時的解析過程變?yōu)椋?br> 1)虛擬機(jī)提取對象的實際類型的方法表
2)虛擬機(jī)搜索定義指定方法簽名的類
3)虛擬機(jī)調(diào)用方法 - 在覆蓋一個方法的時候放前,子類方法不能低于超類方法的可見性。
- 阻止繼承:final類和方法
類中特定的方法也可以被聲明為final糯彬,子類不能覆蓋這個方法凭语。
一個類聲明為final,其中的方法自動成為final撩扒,不包括域似扔。
虛擬機(jī)中的即時編譯器如果發(fā)現(xiàn):方法很簡短、別頻繁調(diào)用且沒有真正被覆蓋,就對其進(jìn)行內(nèi)聯(lián)處理炒辉。 - 強(qiáng)制類型轉(zhuǎn)換豪墅,類似于C++ dynamic_cast
1)只能在繼承層次內(nèi)進(jìn)行類型轉(zhuǎn)換
2)在將超類轉(zhuǎn)換為子類之前,應(yīng)該使用instanceof進(jìn)行檢查
一般情況下黔寇,應(yīng)該盡量少用類型轉(zhuǎn)換和instanceof運(yùn)算符偶器。 - 抽象類——C++的抽象類(包含純虛函數(shù)virtual xxx() = 0;)
關(guān)鍵字abstract
包含一個或多個抽象方法的類必須被聲明為抽象的。
抽象方法不需要實現(xiàn)缝裤。
類即使不含抽象類屏轰,也可以聲明為抽象類。抽象類不能被實例化倘是。
可以定義一個抽象類的對象變量(引用)亭枷,它只能引用非抽象子類的對象。 - 受保護(hù)訪問
總結(jié):
1)僅對本類可見——private
2)對所有類可見——public
3)對本包和所有子類可見——protected
4)對本包可見——默認(rèn)搀崭,不需要修飾符
- Object:所有類的超類
在Java中叨粘,只有基本類型不是對象(比如數(shù)值、字符和布爾類型)
所有數(shù)組類型都擴(kuò)展了Object類瘤睹。 -
equals方法
判斷兩個對象是否具有相同的引用升敲。
編寫一個equals的建議:
- hashCode方法
散列碼是由對象導(dǎo)出的一個整型值。hashCode方法定義在Object類中轰传,因此每個對象都有一個默認(rèn)的散列碼驴党,其值為對象的存儲地址。
Equals與hasnCode的定義必須一直:如果x.equals(y)返回true获茬,那么x.HashCode()必須與y.hashCode()具有相同的值港庄。 - toString方法
返回表示對象值的字符串。
如果x是任意一個對象恕曲,并調(diào)用System.out.println(x);會直接調(diào)用x.toString()鹏氧。
數(shù)組類型需要調(diào)用靜態(tài)方法:Arrays.toString,多維數(shù)組調(diào)用Arrays.deepToString
建議:為自定義的每一個類增加toString方法佩谣,可以讓所有使用這個類的程序員從這個日志記錄支持中受益把还。
- 泛型數(shù)組列表(Java沒有運(yùn)算符重載)
ArrayList是一個采用類型參數(shù)的泛型類,實現(xiàn)動態(tài)數(shù)組茸俭。(跟C++ vector是一樣的)
使用add方法為數(shù)組添加新元素吊履,而不要使用set方法。set方法只能替換數(shù)組中已經(jīng)存在的元素的內(nèi)容调鬓。
- 對象包裝器與自動裝箱
所有的類型都有一個與之對應(yīng)的類艇炎。這些類成為包裝器(wrapper)。
Integer腾窝、Long冕臭、Float腺晾、Double、Short辜贵、Byte悯蝉、Character、Void和Boolean托慨。
對象包裝器類是不可變的鼻由,即一旦構(gòu)造了包裝器,就不允許更改包裝在其中的值厚棵。同時蕉世,對象包裝器類還是final,因此不能定義它們的子類婆硬。
自動裝箱:可以將int類型自動裝箱狠轻,自動變成Integer。
ArrayList<Integer> list = new ArrayList<>();
//自動裝箱
list.add(3);
//自動拆箱
int n = list.get(i);
//將基本方法放置在包裝器中
int x = Integer.parseInt(s); //靜態(tài)方法彬犯,字符串轉(zhuǎn)整型
- Integer對象是不可變的:包含在包裝器中的內(nèi)容不會改變向楼。
修改數(shù)值參數(shù)值的方法,需要使用在org.omg.CORBA中定義的holder類型谐区。
public static void triple(IntHolder x)
{
x.value = 3 * x.value;
}
- Java的可變參數(shù)與數(shù)組是一樣的
- 枚舉聲明定義的類型是一個類湖蜕,并且剛好有定義的數(shù)量個實例。
比較兩個枚舉類的值時宋列,不需要equals昭抒,直接使用==即可。
所有枚舉類都是Enum類的子類炼杖。重要的方法有toString和valueOf灭返。
- 反射庫被大量用于JavaBeans,是Java組件的體系結(jié)構(gòu)坤邪。
能夠分析類能力的程序稱為反射(reflective)熙含。反射機(jī)制用于:
1)在運(yùn)行時分析類的能力
2)在運(yùn)行時查看對象
3)實現(xiàn)通用的數(shù)組操作diamante
4)利用Method對象,這個對象很像C++的函數(shù)指針 - Class類
運(yùn)行時罩扇,Java運(yùn)行時系統(tǒng)為所有的對象維護(hù)一個被稱為運(yùn)行時的類型標(biāo)識婆芦。這個信息跟蹤每個對象所屬的類怕磨。虛擬機(jī)利用運(yùn)行時類型信息選擇相應(yīng)的方法執(zhí)行喂饥。
保存這些信息的類被稱為Class。Object的getClass()方法返回一個Class類型的實例肠鲫。