第十六章 異常機制和file類
16.1 異常機制(重點)
16.1.1 基本概念
所謂的異常就是Java程序在運行過程中發(fā)生了錯誤,出現(xiàn)了不正常的行為流炕,中斷正在執(zhí)行程序的正常指令流澎现;
Java.lang.Throwable類是Java中Error和Exception的基類;
Error稱為錯誤每辟,主要是一些JVM層面的錯誤剑辫,程序開發(fā)人員是無法通過程序去處理的,只能重啟JVM渠欺。例如堆棧溢出妹蔽。
Exception稱為異常,主要是一些程序設(shè)計不嚴(yán)謹(jǐn)所拋出一些異常情況,開發(fā)人員可以事先通過編碼去捕獲處理胳岂。例如典型的空指針異常(NullPointException)编整。
16.1.2 異常的分類
- Throwable類URL圖
上圖所示
異常的分類主要分類兩種:
RuntimeException 非檢測性異常
IOException和其他異常 檢測性異常
判斷檢測性異常和非檢測性異常的區(qū)別:非檢測性異常編譯器無法識別,只有在程序運行的過程中才會發(fā)現(xiàn)乳丰;檢測性
異常是編譯器能夠發(fā)現(xiàn)的
- 代碼demo
System.out.println("-----------非檢測性異常----------");
/**
* 此時編譯器并沒有提示報錯掌测,運行時會拋出Exception in thread "main" java.lang.ArithmeticException: / by zero
*/
System.out.println(4 / 0);
System.out.println("-----------檢測性異常------------");
/**
* 會有紅色波浪線提示unhandledException,此時需要捕獲處理
*/
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
- 注意
一旦程序拋出異常产园,拋出異常地方下面的程序都不會再執(zhí)行汞斧。
16.1.3 異常避免
通常程序開發(fā)使用if判斷語句進行避免異常的發(fā)生
缺點:代碼可讀性差,臃腫
代碼demo
System.out.println("-------------算術(shù)異常------------");
int a = 8;
int b = 0;
if (0 != b) {
System.out.println(a / b);
}
System.out.println("------------下標(biāo)越界異常--------");
int[] arr = new int[5];
int index = 5;
if (arr.length > 0 && arr.length < 5) {
System.out.println(arr);
}
System.out.println("-------------空指針異常----------");
String str = null;
if (null != str) {
System.out.println(str.length());
}
System.out.println("------------類型轉(zhuǎn)換異常---------");
Object it = new Object();
if(it instanceof String) {
String c = (String) it;
}
System.out.println("------------數(shù)據(jù)格式異常---------");
String numStr = "123r";
if (numStr.matches("\\d+")) {
int i = Integer.parseInt(numStr);
System.out.println(i);
}
16.1.6 自定義異常
- 自定義異常類
public class AgeException extends Exception{
/**
* 自定義異常AgeException什燕,用于判斷用戶年齡是否符合要求
*/
public AgeException() {
super();
}
public AgeException(String message) {
super(message);
}
}
- 學(xué)生類
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
/**
* 使用throw進行聲明異常
*
* @param age
* @throws AgeException
*/
public void setAge(int age) throws AgeException {
if (age > 0 && age < 120) {
this.age = age;
} else {
throw new AgeException("年齡不合理");
}
}
public Student(String name, int age) throws AgeException {
setName(name);
setAge(age);
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
- 測試結(jié)果類
/**
* 1. 當(dāng)使用throw的方式進行將一場進行跑出去的時候断箫,由調(diào)用者進行try-catch進行捕獲進行處理的時候,一旦發(fā)生異常就不會生成對象
*
* 打印結(jié)果:
*
* student1 = Student{name='fuyi', age=10}
* com.ryan.stage1.model4.task16.AgeException: 年齡不合理
* at com.ryan.stage1.model4.task16.Student.setAge(Student.java:32)
* at com.ryan.stage1.model4.task16.Student.<init>(Student.java:39)
* at com.ryan.stage1.model4.task16.StudentTest.main(StudentTest.java:13)
*/
try {
Student student1 = new Student("fuyi", 10);
System.out.println("student1 = " + student1);
Student student2 = new Student("Sam", 130);
System.out.println("student2 =" + student2);
} catch (AgeException e) {
e.printStackTrace();
}
- 使用try-catch方式
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
/**
* 使用throw進行聲明異常
*
* @param age
* @throws AgeException
*/
public void setAge(int age) throws AgeException {
if (age > 0 && age < 120) {
this.age = age;
} else {
throw new AgeException("年齡不合理");
}
}
public Student(String name, int age) {
setName(name);
try {
setAge(age);
} catch (AgeException e) {
e.printStackTrace();
}
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
- 測試結(jié)果
/**
* 2. 如果在方法本身內(nèi)部使用try-catch進行捕獲處理秋冰,對象還是會生成
*
* 打印結(jié)果:
* com.ryan.stage1.model4.task16.AgeException: 年齡不合理
* at com.ryan.stage1.model4.task16.Student.setAge(Student.java:32)
* at com.ryan.stage1.model4.task16.Student.<init>(Student.java:45)
* at com.ryan.stage1.model4.task16.StudentTest.main(StudentTest.java:22)
* student3 = Student{name='Lucy', age=0}
*/
Student student3 = new Student("Lucy", 123);
System.out.println("student3 = " + student3);
- 總結(jié)
使用throw和try-catch的區(qū)別: 在于try-catch還是可以進行對象的生成仲义,而使用throw進行拋出異常的時候,此時對象不會生成而為null剑勾。
16.2 File類
16.2.1 基本概念
java.io.File類主要用于描述文件或目錄路徑的抽象表示信息埃撵,可以獲取文件或目錄的特征信息,
如:大小等虽另。
16.2.2 常用的方法
方法聲明 | 功能概述 |
---|---|
File(String pathname) | 根據(jù)參數(shù)指定的路徑名來構(gòu)造對象 |
File(String parent, String child) | 根據(jù)參數(shù)指定的父路徑和子路徑信息構(gòu)造對象 |
File(File parent, String child) | 根據(jù)參數(shù)指定的父抽象路徑和子路徑信息構(gòu)造對象 |
boolean exists() | 測試此抽象路徑名表示的文件或目錄是否存在 |
String getName() | 用于獲取文件的名稱 |
long length() | 返回由此抽象路徑名表示的文件的長度 |
long lastModified() | 用于獲取文件的最后一次修改時間 |
String getAbsolutePath() | 用于獲取絕對路徑信息 |
boolean delete() | 用于刪除文件暂刘,當(dāng)刪除目錄時要求是空目錄 |
boolean createNewFile() | 用于創(chuàng)建新的空文件 |
boolean mkdir() | 用于創(chuàng)建目錄 |
boolean mkdirs() | 用于創(chuàng)建多級目錄 |
File[] listFiles() | 獲取該目錄下的所有內(nèi)容 |
boolean isFile() | 判斷是否為文件 |
boolean isDirectory() | 判斷是否為目錄 |
File[] listFiles(FileFilter filter) | 獲取目錄下滿足篩選器的所有內(nèi)容 |
第十七章 IO流
17.1 IO流的概念
IO就是Input和Output的簡寫。
IO流就是是Java程序讀寫數(shù)據(jù)的一種方式捂刺。流是一種有序的數(shù)據(jù)序列谣拣,將數(shù)據(jù)從一個地方帶到另一個地方。
17.2 基本分類
-
按流的方向
輸出流族展,從程序到文件森缠、網(wǎng)絡(luò)、數(shù)據(jù)庫和其他數(shù)據(jù)源
輸入流仪缸,從文件贵涵、網(wǎng)絡(luò)、數(shù)據(jù)庫和其他數(shù)據(jù)源到程序
如下圖所示
-
按流的數(shù)據(jù)單位
字節(jié)流恰画,以字節(jié)(8位)為單位進行數(shù)據(jù)的讀寫宾茂,可以讀寫任意類型的文件。
字符流拴还,以字符(2個字節(jié))為單位進行數(shù)據(jù)的讀寫跨晴,只能讀取文本文件。
-
按流的功能
節(jié)點流片林,就是指直接和輸入輸出源對接的流端盆。
處理流树瞭,指建立在在節(jié)點流的基礎(chǔ)上的流。
17.3 體系結(jié)構(gòu)
17.4 相關(guān)流的詳解
- 流體系框架圖
17.4.1 FileWriter類(重點)
- 作用
java.lang.FileWriter類主要用于將文本內(nèi)容寫入到文本文件
- 常用構(gòu)造方法
方法聲明 | 功能 |
---|---|
FileWriter?(File file) | 使用平臺的默認(rèn)字符集構(gòu)造給定要寫入文件的FileWriter |
FileWriter?(File file, boolean append) | 使用平臺的默認(rèn)字符集爱谁,構(gòu)造一個FileWriter晒喷,給定要寫入的File和一個布爾值,該布爾值指示是否追加寫入的數(shù)據(jù)访敌。 |
FileWriter?(File file, Charset charset) | 給定File來構(gòu)造FileWriter進行寫和字符集設(shè)置凉敲。 |
代碼demo
FileWriter fileWriter1 = null;
FileWriter fileWriter2 = null;
try {
//1. 構(gòu)造方法一
fileWriter1 = new FileWriter("U:\\Ryan\\lagou-basic\\stage1\\src\\main\\java\\com\\ryan\\stage1\\model4\\task17\\file");
//2. 構(gòu)造方法二(內(nèi)容追加方式)
fileWriter2 = new FileWriter("U:\\Ryan\\lagou-basic\\stage1\\src\\main\\java\\com\\ryan\\stage1\\model4\\task17\\file", true);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fileWriter1 != null || fileWriter2 != null) {
//關(guān)閉資源
try {
fileWriter1.close();
fileWriter2.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 常用方法
代碼demo
System.out.println("--------------------------FileWriter類常用方法--------------------------------------");
/**
* 1. 寫入單個字符,
*/
fileWriter1.write("B"); // B
/**
* 2. 將指定字符數(shù)組中從偏移量off開始的len個字符寫入此文件輸出流
*/
char[] cArr = new char[]{'a', 'b', 'c', 'd'};
fileWriter1.write(cArr, 1, 3); // bcd
/**
* 3. 將cbuf.length個字符從指定字符數(shù)組寫入此文件輸出流中
*/
fileWriter1.write(cArr); // bcdabcd
/**
* 4. 刷新流
*/
fileWriter1.flush();
/**
* 5. 關(guān)閉流對象釋放有關(guān)的資源
*/
fileWriter1.close();
17.4.2 FileReader類(重點)
- 作用
java.lang.FileReader類主要用于從文本文件讀取文本數(shù)據(jù)內(nèi)容
- 常用構(gòu)造方法
代碼demo
System.out.println("-------------構(gòu)造方法-----------------");
//1. 構(gòu)造方法一
FileReader fileReader1 = null;
try {
fileReader1 = new FileReader("U:/Ryan/lagou-basic/stage1//src/main/java/com/ryan/stage1/model4/task17/file/myFile.txt");
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (fileReader1 != null) {
try {
fileReader1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 常用類方法
代碼demo
System.out.println("----------------常用方法-------------------------");
/**
* 1. 讀取單個字符的數(shù)據(jù)并返回,返回-1表示讀取到末尾
*/
int read = fileReader1.read();
System.out.println((char) read); // B
/**
* 2. 讀取全部
*/
while (fileReader1.read() != -1) {
int read1 = fileReader1.read();
System.out.println("字符為:" + (char) read1);
}
/**
* 3. 從輸入流中將最多l(xiāng)en個字符的數(shù)據(jù)讀入一個字符數(shù)組中,返回讀取到的字符個數(shù)蝉衣,返回-1表示讀取到末尾
*/
char[] cArr = new char[5];
fileReader1.read(cArr, 0, 5);
System.out.println(cArr); // Bbcda
/** 4. 關(guān)閉流對象措伐,釋放資源
*/
fileReader1.close();
17.4.3 FileOutputStream類(重點)
上述的兩個類主要對文件進行讀寫操作圾浅,但是對于音頻和視頻是不能進行讀寫,就算讀寫成功也是解析不出來,因此下面介紹能夠讀取任意文件類型的
文件流類
- 作用
java.io.FileOutputStream類主要用于將圖像數(shù)據(jù)之類的原始字節(jié)流寫入到輸出流中。
- 構(gòu)造方法
代碼demo
System.out.println("-------------------構(gòu)造方法-----------------------");
FileOutputStream fileOutputStream1 = null;
FileOutputStream fileOutputStream2 = null;
/**
* 創(chuàng)建文件輸出流以寫入具有指定名稱的文件
*/
try {
//1. 構(gòu)造一 (如果文件不存在會自動創(chuàng)建一個空白文件)
fileOutputStream1 = new FileOutputStream("e:/myFile.txt");
//2. 構(gòu)造二 (進行追加內(nèi)容)
fileOutputStream2 = new FileOutputStream("e:/myFile.txt",true);
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (null != fileOutputStream1) {
try {
fileOutputStream1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != fileOutputStream2) {
try {
fileOutputStream2.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 常用方法
System.out.println("-------------------構(gòu)造方法-----------------------");
FileOutputStream fileOutputStream1 = null;
FileOutputStream fileOutputStream2 = null;
/**
* 創(chuàng)建文件輸出流以寫入具有指定名稱的文件
*/
try {
//1. 構(gòu)造一 (如果文件不存在會自動創(chuàng)建一個空白文件)
fileOutputStream1 = new FileOutputStream("e:/myFile.txt");
//2. 構(gòu)造二 (進行追加內(nèi)容)
fileOutputStream2 = new FileOutputStream("e:/myFile.txt",true);
System.out.println("--------------------常用方法----------------------");
/**
* 1. 將指定字節(jié)寫入此文件輸出流
*/
fileOutputStream1.write('G');
/**
* 2. 將指定字節(jié)數(shù)組中從偏移量off開始的len個字節(jié)寫入此文件輸出流
*/
byte[] arr = new byte[] {65, 66, 67, 68};
fileOutputStream1.write(arr);
/**
* 3. 刷新此輸出流并強制寫出任何緩沖的輸出字節(jié)
*/
fileOutputStream1.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != fileOutputStream1) {
try {
/**
* 4. 關(guān)閉流對象并釋放有關(guān)的資源
*/
fileOutputStream1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != fileOutputStream2) {
try {
fileOutputStream2.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 總結(jié)
17.4.4 FileInputStream類(重點)
- 作用
java.io.FileInputStream類主要用于從輸入流中以字節(jié)流的方式讀取圖像數(shù)據(jù)等渤昌。
- 構(gòu)造方法
代碼demo
System.out.println("-----------------構(gòu)造方法------------------------");
FileInputStream fileInputStream1 = null;
try {
fileInputStream1= new FileInputStream("e:/myFile.txt");
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (null != fileInputStream1) {
try {
/**
* 4. 關(guān)閉流對象并釋放有關(guān)的資源
*/
fileInputStream1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 常用方法
System.out.println("-----------------構(gòu)造方法------------------------");
FileInputStream fileInputStream1 = null;
try {
fileInputStream1= new FileInputStream("e:/myFile.txt");
System.out.println("----------------常用方法----------------------");
/**
* 1. 從輸入流中讀取單個字節(jié)的數(shù)據(jù)并返回,返回-1表示讀取到末尾
* 注意:這里調(diào)用read()方法和迭代器itertor.next()方法是一樣走搁,每調(diào)用一次独柑,游標(biāo)向下移動一次
*/
int read = fileInputStream1.read();
System.out.println((char) read);
while ((read = fileInputStream1.read()) != -1) {
System.out.println((char) read); // A B C D
}
while (fileInputStream1.read() != -1) {
System.out.println((char) fileInputStream1.read()); // B D
}
/**
* 2. 從此輸入流中將最多 b.length 個字節(jié)的數(shù)據(jù)讀入字節(jié)數(shù)組中,返回讀取到的字節(jié)個數(shù)私植,返回-1表示讀取到末尾
*/
byte[] brr = new byte[5];
fileInputStream1.read(brr);
for (byte b : brr) {
System.out.print(b); // 71 65 66 67 68
}
/**
* 3. 獲取輸入流所關(guān)聯(lián)文件的大小
*/
System.out.println("輸入流大小為:" + fileInputStream1.available());// 5
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != fileInputStream1) {
try {
/**
* 4. 關(guān)閉流對象并釋放有關(guān)的資源
*/
fileInputStream1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 文件拷貝
//測試拷貝效率
long start = System.currentTimeMillis();
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
try {
//1. 創(chuàng)建文件輸入流
fileInputStream = new FileInputStream("e:/myFile.txt");
//2. 創(chuàng)建文件輸出流
fileOutputStream = new FileOutputStream("e:/myFileCopys.txt");
//3. 讀取一個字節(jié)然后寫入一個字節(jié)
int read = 0;
while ((read = fileInputStream.read()) != -1) {
fileOutputStream.write(read);
}
//4. 使用緩存分多少次進行讀寫
byte[] brr = new byte[1024];
int length = 0;
while ((length = fileInputStream.read(brr)) != -1) {
fileOutputStream.write(brr, 0, length);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//關(guān)閉資源
if (null != fileInputStream) {
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != fileOutputStream) {
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
long end = System.currentTimeMillis();
System.out.println("Copy消耗時間" + (end - start) + "ms"); //9ms
System.out.println("緩存方式Copy消耗時間" + (end - start) + "ms"); //1ms
-
總結(jié)
這里調(diào)用read()方法和迭代器itertor.next()方法是一樣忌栅,每調(diào)用一次,游標(biāo)向下移動一次曲稼;讀取完后想要重新再讀取一遍需要重新創(chuàng)建一個流對象
通過上面兩個類可以實現(xiàn)文件的拷貝索绪,拷貝的方式有三種:第一種是逐個字節(jié)讀取并寫入,缺點就是文件過大時候贫悄,花費時間很長瑞驱;
第二種是通過將文件讀入到一個文件大小的字節(jié)數(shù)組緩沖區(qū)里面,讀取完畢再一并寫入清女,缺點就是文件過大占用較大的物理內(nèi)存空間钱烟;
第三種是在第二種的基礎(chǔ)上通過分批多次讀取并寫入,相對前面兩種來說效率得到提升和資源開銷也減少了嫡丙。
17.4.5 BufferedOutputStream類(重點)
上面章節(jié)結(jié)束的時候,我們使用自定義緩存的方式進行讀寫copy文件读第,Java官方也提供了這種緩存式的讀寫操作的類曙博。本章節(jié)就繼續(xù)討論緩存式讀寫操作類
- 作用
java.io.BufferedOutputStream類主要用于描述緩沖輸出流,此時不用為寫入的每個字節(jié)調(diào)用底層系統(tǒng)怜瞒。
- 構(gòu)造方法
代碼demo
BufferedOutputStream bos = null;
System.out.println("---------------------構(gòu)造方法---------------------------");
try {
// 1.創(chuàng)建BufferedOutputStream類型的對象與e:/myFile.txt流的框架結(jié)構(gòu).txt文件關(guān)聯(lián)
bos = new BufferedOutputStream(new FileOutputStream("e:/myFile.txt"));
} catch (IOException e) {
e.printStackTrace();
} finally {
// 4.關(guān)閉流對象并釋放有關(guān)的資源
if (null != bos) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 常用方法
BufferedOutputStream bos = null;
System.out.println("---------------------構(gòu)造方法---------------------------");
try {
// 1.創(chuàng)建BufferedOutputStream類型的對象與e:/myFile.txt流的框架結(jié)構(gòu).txt文件關(guān)聯(lián)
bos = new BufferedOutputStream(new FileOutputStream("e:/myFile.txt"));
System.out.println("--------------------常用方法----------------------");
/**
* 1. 將指定字節(jié)寫入此文件輸出流
*/
bos.write('G');
/**
* 2. 將指定字節(jié)數(shù)組中從偏移量off開始的len個字節(jié)寫入此文件輸出流
*/
byte[] arr = new byte[] {65, 66, 67, 68};
bos.write(arr);
/**
* 3. 刷新此輸出流并強制寫出任何緩沖的輸出字節(jié)
*/
bos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
// 4.關(guān)閉流對象并釋放有關(guān)的資源
if (null != bos) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
-
總結(jié)
和上面的的流對象相比父泳,只是構(gòu)造方法的不同般哼,其他的常用方法都是一樣,后就不再加以贅述了惠窄。
17.4.6 BufferedInputStream類(重點)
- 作用
java.io.BufferedInputStream類主要用于描述緩沖輸入流蒸眠。
- 構(gòu)造方法
代碼demo
BufferedInputStream bis = null;
System.out.println("-------------------構(gòu)造方法-------------------");
try {
new BufferedInputStream(new FileInputStream("e:/myFile.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (null != bis) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 常用方法
參考FileInputStream
- 文件拷貝
// 獲取當(dāng)前系統(tǒng)時間距離1970年1月1日0時0分0秒的毫秒數(shù)
long g1 = System.currentTimeMillis();
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
// 1.創(chuàng)建BufferedInputStream類型的對象與e:/myFile.txt文件關(guān)聯(lián)
bis = new BufferedInputStream(new FileInputStream("e:/myFile.txt"));
// 2.創(chuàng)建BufferedOuputStream類型的對象與e:/myFileCopys.txt文件關(guān)聯(lián)
bos = new BufferedOutputStream(new FileOutputStream("e:/myFileCopys.txt"));
// 3.不斷地從輸入流中讀取數(shù)據(jù)并寫入到輸出流中
byte[] bArr = new byte[1024];
int res = 0;
while ((res = bis.read(bArr)) != -1) {
bos.write(bArr, 0, res);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 4.關(guān)閉流對象并釋放有關(guān)的資源
if (null != bos) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != bis) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
long g2 = System.currentTimeMillis();
System.out.println("使用緩沖區(qū)拷貝文件消耗的時間為:" + (g2-g1)); // 1ms
17.4.7 BufferedWrite類(重點)
- 作用
java.io.BufferedWriter類主要用于寫入單個字符、字符數(shù)組以及字符串到輸出流中杆融。
- 構(gòu)造方法
代碼demo
System.out.println("-----------構(gòu)造方法--------------");
BufferedWriter bufferedWriter1 = null;
try {
bufferedWriter1 = new BufferedWriter(new FileWriter("e:/myFile.txt"));
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != bufferedWriter1) {
try {
/**
* 6. 關(guān)閉資源
*/
bufferedWriter1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 常用方法
System.out.println("-----------構(gòu)造方法--------------");
BufferedWriter bufferedWriter1 = null;
try {
bufferedWriter1 = new BufferedWriter(new FileWriter("e:/myFile.txt"));
System.out.println("-------常用方法--------------");
/**
* 1. 寫入單個字符到輸出流中
*/
bufferedWriter1.write(70);
/**
* 2. 將字符串?dāng)?shù)組cbuf中所有內(nèi)容寫入輸出流中
*/
char[] cArr = new char[] {'b', 'n', 'y'};
bufferedWriter1.write(cArr);
/**
* 3. 將參數(shù)指定的字符串內(nèi)容寫入輸出流中
*/
bufferedWriter1.write("fuyi");
/**
* 4. 用于寫入行分隔符到輸出流中
*/
bufferedWriter1.newLine();
bufferedWriter1.write(cArr);
/**
* 5. 刷新流
*/
bufferedWriter1.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != bufferedWriter1) {
try {
/**
* 6. 關(guān)閉資源
*/
bufferedWriter1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 總結(jié)
17.4.8 BufferedRead類(重點)
- 作用
java.io.BufferedReader類用于從輸入流中讀取單個字符楞卡、字符數(shù)組以及字符串。
- 構(gòu)造方法
代碼demo
System.out.println("--------------構(gòu)造方法------------------");
BufferedReader bufferedReader1 = null;
try {
bufferedReader1 = new BufferedReader(new FileReader("e:/myFile.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (null != bufferedReader1) {
try {
bufferedReader1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 常用方法
BufferedReader bufferedReader1 = null;
try {
bufferedReader1 = new BufferedReader(new FileReader("e:/myFile.txt"));
System.out.println("-----------------常用方法---------------");
/**
* 1. 從輸入流讀取單個字符脾歇,讀取到末尾則返回-1蒋腮,否則返回實際讀取到的字符內(nèi)容
*/
int read = bufferedReader1.read();
System.out.println((char) read);
/**
* 2. 從輸入流中讀滿整個數(shù)組cbuf
*/
char[] crr = new char[5];
bufferedReader1.read(crr);
System.out.println(crr);
/**
* 3. 讀取一行字符串并返回,返回null表示讀取到末尾
*/
String str = null;
while ((str = bufferedReader1.readLine()) != null) {
System.out.println(str);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != bufferedReader1) {
try {
/**
* 4. 關(guān)閉資源
*/
bufferedReader1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 總結(jié)
17.4.9 PrintStream類(重點)
- 作用
java.io.PrintStream類主要用于更加方便地打印各種數(shù)據(jù)內(nèi)容藕各。
- 構(gòu)造方法
代碼demo
System.out.println("---------------構(gòu)造方法------------------");
PrintStream printStream1 = null;
try {
printStream1 = new PrintStream(new FileOutputStream("e:/myFile.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (null != printStream1) {
printStream1.close();
}
}
- 常用方法
PrintStream printStream1 = null;
try {
printStream1 = new PrintStream(new FileOutputStream("e:/myFile.txt"));
System.out.println("-----------------常用方法-------------------");
/**
* 1. 用于將參數(shù)指定的字符串內(nèi)容打印出來
*/
printStream1.print("fuyinb");
/**
* 2. 用于打印字符串后并終止該行
*/
printStream1.println("cheshigailei");
printStream1.println("另起一行");
/**
* 3. 刷新流
*/
printStream1.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (null != printStream1) {
/**
* 4. 關(guān)閉流
*/
printStream1.close();
}
}
- 總結(jié)
17.4.10 PrintWriter類
- 作用
java.io.PrintWriter類主要用于將對象的格式化形式打印到文本輸出流池摧。
- 構(gòu)造方法
代碼demo
System.out.println("-------------------構(gòu)造方法-------------------");
PrintWriter printWriter1 = null;
try {
printWriter1 = new PrintWriter(new FileWriter("e:/myChat.txt"));
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != printWriter1) {
printWriter1.close();
}
}
- 常用方法
參考PrintWriter類
- 總結(jié)
17.4.11 OutputStreamWriter類(重點)
- 作用
java.io.OutputStreamWriter類主要用于實現(xiàn)從字符流到字節(jié)流的轉(zhuǎn)換。
- 構(gòu)造方法
代碼demo
OutputStreamWriter outputStreamWriter1 = null;
OutputStreamWriter outputStreamWriter2 = null;
try {
//構(gòu)造方法一
outputStreamWriter1 = new OutputStreamWriter(new FileOutputStream("e:/myFile.txt"));
//構(gòu)造方法二
outputStreamWriter2 = new OutputStreamWriter(new FileOutputStream("e:/myFile.txt"), "utf-8");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != outputStreamWriter1) {
try {
/**
* 3. 關(guān)閉流
*/
outputStreamWriter1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != outputStreamWriter2) {
try {
outputStreamWriter2.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 常用方法
System.out.println("------------------常用方法-------------------");
/**
* 1. 將參數(shù)指定的字符串寫入
*/
outputStreamWriter1.write(68);
outputStreamWriter1.write("jshgh");
outputStreamWriter1.write('j');
/**
* 2. 刷新流
*/
outputStreamWriter1.flush();
/**
* 3. 關(guān)閉流
*/
outputStreamWriter1.close();
- 總結(jié)
17.4.12 InputStreamReader類(重點)
- 作用
java.io.InputStreamReader類主要用于實現(xiàn)從字節(jié)流到字符流的轉(zhuǎn)換激况。
- 常用方法
方法聲明 | 功能介紹 |
---|---|
InputStreamReader(InputStream in) | 根據(jù)參數(shù)指定的引用來構(gòu)造對象 |
InputStreamReader(InputStream in, String charsetName) | 根據(jù)參數(shù)指定的引用和編碼來構(gòu)造對象 |
int read(char[] cbuf) | 讀取字符數(shù)據(jù)到參數(shù)指定的數(shù)組 |
void close() | 用于關(guān)閉輸出流并釋放有關(guān)的資源 |
17.4.13 字符編碼
-
背景
- 計算機只能識別二進制數(shù)據(jù)作彤,早期就是電信號。為了方便計算機可以識別各個國家的文字乌逐,就需要
將各個國家的文字采用數(shù)字編號的方式進行描述并建立對應(yīng)的關(guān)系表宦棺,該表就叫做編碼表。
- 計算機只能識別二進制數(shù)據(jù)作彤,早期就是電信號。為了方便計算機可以識別各個國家的文字乌逐,就需要
-
常見編碼
GBK
UTF-8
ASCII
發(fā)展
17.4.14 DataOutputStream類(了解)
- 作用
java.io.DataOutputStream類主要用于以適當(dāng)?shù)姆绞綄⒒緮?shù)據(jù)類型寫入輸出流中黔帕。
- 常用方法
代碼demo
DataOutputStream dataOutputStream = null;
try {
dataOutputStream = new DataOutputStream(new FileOutputStream("e:/myFile.txt"));
System.out.println("-------------------常用方法---------------------");
/**
* 1. 用于將參數(shù)指定的整數(shù)一次性寫入輸出流代咸,優(yōu)先寫入高字節(jié)
*/
dataOutputStream.writeInt(67); // C
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != dataOutputStream) {
try {
dataOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
17.4.14 DataInputStream類(了解)
- 作用
java.io.DataInputStream類主要用于以適當(dāng)?shù)姆绞綇妮斎肓髦凶x取基本數(shù)據(jù)類型的數(shù)據(jù)。
- 常用方法
DataInputStream dis = null;
try {
// 1.創(chuàng)建DataInputStream類型的對象與d:/a.txt文件關(guān)聯(lián)
dis = new DataInputStream(new FileInputStream("e:/myFile.txt"));
// 2.從輸入流中讀取一個整數(shù)并打印
int res = dis.readInt(); // 讀取4個字節(jié)
//int res = dis.read(); // 讀取1個字節(jié)
System.out.println("讀取到的整數(shù)數(shù)據(jù)是:" + res); // 67
} catch (IOException e) {
e.printStackTrace();
} finally {
// 3.關(guān)閉流對象并釋放有關(guān)的資源
if (null != dis) {
try {
dis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
17.4.15 序列化與反序列化
-
基本概念
序列化 (對象 -> 字節(jié)流)
反序列化 (字節(jié)流 -> 對象)
-
序列化版本號
在 序列化存儲/反序列化讀取 或者是 序列化傳輸/反序列化接收 時成黄,JVM 會把傳來的字節(jié)流中的serialVersionUID與本地相應(yīng)實體(類)的serialVersionUID進行比較呐芥,如果相同就認(rèn)為是一致的,可以進行反序列化奋岁,否則就會出現(xiàn)序列化版本不一致的異常思瘟。
-
transient關(guān)鍵字
在Java中,當(dāng)一個類實現(xiàn)了java.io.Serializable接口闻伶,即表明了該類可以被序列化滨攻。我們可以把該類的屬性序列化然后保存在外部,或者跟另外一個jvm進行數(shù)據(jù)傳遞蓝翰。但是光绕,我們是否想過,如果一個類包含隱私信息畜份,如用戶的密碼等诞帐,那么這個屬性就不能夠被序列化到外部。當(dāng)然爆雹,我們可以在序列化之前手動set該值為null停蕉,但是最優(yōu)雅的做法就是使用transient關(guān)鍵字愕鼓。
17.4.16 ObjectOutputStream類(重點)
-
作用
java.io.ObjectOutputStream類主要用于將一個對象的所有內(nèi)容整體寫入到輸出流中。
只能將支持 java.io.Serializable 接口的對象寫入流中慧起。
類通過實現(xiàn) java.io.Serializable 接口以啟用其序列化功能菇晃。
所謂序列化主要指將一個對象需要存儲的相關(guān)信息有效組織成字節(jié)序列的轉(zhuǎn)化過程。
常用方法
ObjectOutputStream oos = null;
try {
// 1.創(chuàng)建ObjectOutputStream類型的對象與d:/a.txt文件關(guān)聯(lián)
oos = new ObjectOutputStream(new FileOutputStream("e:/myFile.txt"));
// 2.準(zhǔn)備一個Student類型的對象并初始化
Student student = new Student("fuyi", "123456");
// 3.將整個Student類型的對象寫入輸出流
oos.writeObject(student);
System.out.println("寫入對象成功蚓挤!");
} catch (IOException e) {
e.printStackTrace();
} finally {
// 4.關(guān)閉流對象并釋放有關(guān)的資源
if (null != oos) {
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
17.4.17 ObjectInputStream類(重點)
-
作用
java.io.ObjectInputStream類主要用于從輸入流中一次性將對象整體讀取出來磺送。
常用方法
ObjectInputStream ois = null;
try {
// 1.創(chuàng)建ObjectInputStream類型的對象與d:/a.txt文件關(guān)聯(lián)
ois = new ObjectInputStream(new FileInputStream("e:/myFile.txt"));
// 2.從輸入流中讀取一個對象并打印
Object obj = ois.readObject();
System.out.println("讀取到的對象是:" + obj); // fuyi 123456
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
// 3.關(guān)閉流對象并釋放有關(guān)的資源
if (null != ois) {
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
-
編程開發(fā)經(jīng)驗
當(dāng)希望將多個對象寫入文件時,通常建議將多個對象放入一個集合中屈尼,然后將集合這個整體看做一
個對象寫入輸出流中册着,此時只需要調(diào)用一次readObject方法就可以將整個集合的數(shù)據(jù)讀取出來,
從而避免了通過返回值進行是否達到文件末尾的判斷脾歧。
17.4.18 RandomAccessFile類
-
作用
java.io.RandomAccessFile類主要支持對隨機訪問文件的讀寫操作甲捏。
常用方法
方法聲明 | 功能介紹 |
---|---|
RandomAccessFile(String name, String mode) | 根據(jù)參數(shù)指定的名稱和模式構(gòu)造對象 r: 以只讀方式打開 rw:打開以便讀取和寫入 rwd:打開以便讀取和寫入,同步文件內(nèi)容的更新 rws:打開以便讀取和寫入鞭执,同步文件內(nèi)容和元數(shù)據(jù)的更新 |
int read() | 讀取單個字節(jié)的數(shù)據(jù) |
void seek(long pos) | 用于設(shè)置從此文件的開頭開始測量的文件指針偏移量 |
void write(int b) | 將參數(shù)指定的單個字節(jié)寫入 |
void close() | 用于關(guān)閉流并釋放有關(guān)的資源 |
- 代碼demo
RandomAccessFile raf = null;
try {
// 1.創(chuàng)建RandomAccessFile類型的對象與d:/a.txt文件關(guān)聯(lián)
raf = new RandomAccessFile("e:/myFile.txt", "rw");
// 2.對文件內(nèi)容進行隨機讀寫操作
// 設(shè)置距離文件開頭位置的偏移量司顿,從文件開頭位置向后偏移3個字節(jié) aellhello
raf.seek(3);
int res = raf.read();
System.out.println("讀取到的單個字符是:" + (char)res); // a l
res = raf.read();
System.out.println("讀取到的單個字符是:" + (char)res); // h 指向了e
raf.write('2'); // 執(zhí)行該行代碼后覆蓋了字符'e'
System.out.println("寫入數(shù)據(jù)成功!");
} catch (IOException e) {
e.printStackTrace();
} finally {
// 3.關(guān)閉流對象并釋放有關(guān)的資源
if (null != raf) {
try {
raf.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
第十八章 多線程
18.1 基本概念
18.1.1 程序和進程
-
程序
數(shù)據(jù)結(jié)構(gòu) + 算法兄纺,主要指存放在硬盤上的可執(zhí)行文件大溜。
-
進程
主要指運行在內(nèi)存中的可執(zhí)行文件。
目前主流的操作系統(tǒng)都支持多進程估脆,為了讓操作系統(tǒng)同時可以執(zhí)行多個任務(wù)钦奋,但進程是重量級的,
也就是新建一個進程會消耗CPU和內(nèi)存空間等系統(tǒng)資源疙赠,因此進程的數(shù)量比較局限付材。
18.1.2 線程
為了解決上述問題就提出線程的概念,線程就是進程內(nèi)部的程序流圃阳,也就是說操作系統(tǒng)內(nèi)部支持多
進程的厌衔,而每個進程的內(nèi)部又是支持多線程的,線程是輕量的捍岳,新建線程會共享所在進程的系統(tǒng)資
源富寿,因此目前主流的開發(fā)都是采用多線程。多線程是采用時間片輪轉(zhuǎn)法來保證多個線程的并發(fā)執(zhí)行锣夹,所謂并發(fā)就是指宏觀并行微觀串行的機
制页徐,本質(zhì)上還是串行的,只不過是先CPU切換線程的速度很快晕城,所以看起來是并行執(zhí)行泞坦。
18.2 線程的創(chuàng)建(無比重要)
18.2.1 Thread類的概念
java.lang.Thread類代表線程,任何線程對象都是Thread類(子類)的實例贰锁。
Thread類是線程的模板,封裝了復(fù)雜的線程開啟等操作览闰,封裝了操作系統(tǒng)的差異性。
18.2.2 創(chuàng)建方式
- 自定義類繼承Thread類并重寫run方法,然后創(chuàng)建該類的對象調(diào)用start方法。
代碼demo
class PrimeThread extends Thread {
long minPrime;
PrimeThread(long minPrime) {
this.minPrime = minPrime;
}
public void run() {
// compute primes larger than minPrime
}
}
啟動線程
public class test {
public static void main(String[] args){
PrimeThread p = new PrimeThread(143);
p.start();
}
}
- 自定義類實現(xiàn)Runnable接口并重寫run方法蟹腾,創(chuàng)建該類的對象作為實參來構(gòu)造Thread類型的對
象,然后使用Thread類型的對象調(diào)用start方法。
代碼demo
class PrimeRun implements Runnable {
long minPrime;
PrimeRun(long minPrime) {
this.minPrime = minPrime;
}
public void run() {
// compute primes larger than minPrime
}
}
啟動線程
public class test {
public static void main(String[] args){
PrimeRun p = new PrimeRun(143);
new Thread(p).start();
}
}
18.2.3 常用方法
方法聲明 | 功能介紹 |
---|---|
Thread() | 使用無參的方式構(gòu)造對象 |
Thread(String name) | 根據(jù)參數(shù)指定的名稱來構(gòu)造對象 |
Thread(Runnable target) | 根據(jù)參數(shù)指定的引用來構(gòu)造對象螟炫,其中Runnable是個接口類型 |
Thread(Runnable target,String name) | 根據(jù)參數(shù)指定引用和名稱來構(gòu)造對象 |
void run() | 若使用Runnable引用構(gòu)造了線程對象然评,調(diào)用該方法時最終調(diào)用接口中的版本若沒有使用Runnable引用構(gòu)造線程對象,調(diào)用該方法時則啥也不做 |
void start() | 用于啟動線程纳像,Java虛擬機會自動調(diào)用該線程的run方法 |
代碼demo
/**
* 測試Thread的無參構(gòu)造方法的所創(chuàng)建的對象調(diào)用run()方法是否是啥也沒干
*
* Thread源碼分析
* 首先new Thread()進入無參構(gòu)造方法:
* -> 1. init(null, null, "Thread-" + nextThreadNum(), 0);
* -> 2. private void init(ThreadGroup g, Runnable target, String name,
* long stackSize) {
* init(g, target, name, stackSize, null, true);
* }
* -> 3. 在init方法中因為我們傳入的target = null, 又因為在init的方法中this.target = target;所以此時的target == null
*/
Thread thread = new Thread();
/**
* run()方法源碼:
* -> 4. if (target != null) {
* target.run();
* }
* -> 結(jié)論:沒有執(zhí)行run()方法
*/
thread.run();
System.out.println("測試結(jié)果L妒蕖!");
測試run()和start()方法
public class SubThreadTest extends Thread {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("SubThreadTeat子線程打印" + i);
}
}
}
代碼測試
/**
* 測試線程構(gòu)造方法一的啟動
*/
//1. 創(chuàng)建一個Thread父類的引用指向子類SubThreadTest的對象
Thread thread1 = new SubThreadTest();
//2. run()
//注意:調(diào)用run()方法其實并沒有啟動一個子線程铸本,只不過是執(zhí)行SubThreadTest類中的run()锡足,還是又主線程main進行執(zhí)行指令
thread1.run();
//真正啟動一條線程,本質(zhì)是JVM會去啟動一條線程,用來執(zhí)行SubThreadTest類中的run()方法代碼
thread1.start();
//3. 主線程main方法中打印
for (int i = 0; i < 10; i++) {
System.out.println("主線程main打幽グ:" + i);
}
線程構(gòu)造方法二
public class SubRunnable implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("SubRunnable子線程打印" + i);
}
}
}
測試運行
SubRunnable subRunnable = new SubRunnable();
/**
* 由Thread源碼可得target = subRunnable
*/
Thread thread = new Thread(subRunnable);
/**
* if (target != null) {
* target.run();
* }
* 而此時的target = subRunnable, 所以調(diào)用的是SubRunnable.run()方法
*/
thread.start();
for (int i = 0; i < 10; i++) {
System.out.println("主線程main打印" + i);
}
18.2.4 執(zhí)行流程
執(zhí)行main方法的線程叫做主線程设预,執(zhí)行run方法的線程叫做新線程/子線程宾符。
main方法是程序的入口哄褒,對于start方法之前的代碼來說链嘀,由主線程執(zhí)行一次,當(dāng)start方法調(diào)用成功后線程的個數(shù)由1個變成了2個,新啟動的線程去執(zhí)行run方法的代碼熄驼,主線程繼續(xù)向下執(zhí)行筷笨,兩個線程各自獨立運行互不影響。
當(dāng)run方法執(zhí)行完畢后子線程結(jié)束审胸,當(dāng)main方法執(zhí)行完畢后主線程結(jié)束映企。
兩個線程執(zhí)行沒有明確的先后執(zhí)行次序,由操作系統(tǒng)調(diào)度算法來決定焚挠。
18.2.5 方式比較
18.2.6 匿名內(nèi)部類方式
實現(xiàn)兩種線程創(chuàng)建的代碼編寫
/**
* 1. 原始語法
*/
// 繼承Thread類的方式
Thread thread = new Thread() {
@Override
public void run() {
System.out.println("匿名方式創(chuàng)建");
}
};
thread.start();
// 實現(xiàn)Runnable接口的方式
Runnable ra = new Runnable() {
@Override
public void run() {
System.out.println("匿名方式創(chuàng)建");
}
};
Thread thread1 = new Thread(ra);
thread1.start();
/**
* 2. JDK8的lambda語法
*/
new Thread(() -> System.out.println("lambda匿名方式創(chuàng)建")).start();
18.3 線程的聲明周期
18.4 線程的編號和名稱
方法聲明 | 功能介紹 |
---|---|
long getId() | 獲取調(diào)用對象所表示線程的編號 |
String getName() | 獲取調(diào)用對象所表示線程的名稱 |
void setName(String name) | 設(shè)置/修改線程的名稱為參數(shù)指定的數(shù)值 |
static Thread currentThread() | 獲取當(dāng)前正在執(zhí)行線程的引用 |
代碼示例
public class ThreadIdNameTest extends Thread{
public ThreadIdNameTest(String name) {
super(name);
}
public ThreadIdNameTest() {
}
/**
* 測試對線程id和name的管理
*/
@Override
public void run() {
System.out.println("子線程的信息:");
System.out.println("子線程的名字:" + getName());
System.out.println("子線程的Id:" + getId());
}
public static void main(String[] args) {
/**
* 結(jié)果打印
* 子線程的名字:Thread-0
* 子線程的Id:12
*/
Thread thread = new ThreadIdNameTest();
thread.start();
/**
* 修改線程名 fuyi
* 子線程的名字:fuyi
* 子線程的Id:13
*/
ThreadIdNameTest thread2 = new ThreadIdNameTest("fuyi");
thread2.start();
/**
* 獲取當(dāng)前主線程
* 主線程名字為:main
* 主線程ID為:1
*/
Thread thread1 = Thread.currentThread();
System.out.println("主線程名字為:" + thread1.getName());
System.out.println("主線程ID為:" + thread1.getId());
}
}
實現(xiàn)接口的方式
public class RunnableIdNameTest implements Runnable {
@Override
public void run() {
// 獲取當(dāng)前子線程名字
Thread thread = Thread.currentThread();
System.out.println("子線程的名字為:" + thread.getName());
System.out.println("子線程的ID為:" + thread.getId());
}
public static void main(String[] args) {
/**
* 無參方式創(chuàng)建啟動線程
* 結(jié)果打优鹕怼:
* 子線程的名字為:Thread-0
* 子線程的ID為:12
*/
new Thread(new RunnableIdNameTest()).start();
/**
* 設(shè)置線程名構(gòu)造
* 結(jié)果打印
* 子線程的名字為:fuyi
* 子線程的ID為:13
*/
new Thread(new RunnableIdNameTest(),"fuyi").start();
System.out.println("主線程" + Thread.currentThread().getName());
}
}
18.5 常用方法
方法聲明 | 功能介紹 |
---|---|
static void yield() | 當(dāng)前線程讓出處理器(離開Running狀態(tài))跪另,使當(dāng)前線程進入Runnable狀態(tài)等待 |
static void sleep(times) | 使當(dāng)前線程從 Running 放棄處理器進入Block狀態(tài), 休眠times毫秒, 再返回到Runnable如果其他線程打斷當(dāng)前線程的Block(sleep), 就會發(fā)生InterruptedException。 |
int getPriority() | 獲取線程的優(yōu)先級void setPriority(int newPriority)修改線程的優(yōu)先級彤枢。優(yōu)先級越高的線程不一定先執(zhí)行狰晚,但該線程獲取到時間片的機會會更多一些 |
void join() | 等待該線程終止 |
void join(long millis) | 等待參數(shù)指定的毫秒數(shù) |
boolean isDaemon() | 用于判斷是否為守護線程 |
void setDaemon(boolean on) | 用于設(shè)置線程為守護線程 |
18.6 線程同步機制(重點)
18.6.1 背景
- 當(dāng)多個線程同時訪問同一種共享資源時,可能會造成數(shù)據(jù)的覆蓋等不一致性問題缴啡,此時就需要對線程之間進行通信和協(xié)調(diào)壁晒,該機制就叫做線程的同步機制。
- 多個線程并發(fā)讀寫同一個臨界資源時會發(fā)生線程并發(fā)安全問題业栅。
- 異步操作:多線程并發(fā)的操作秒咐,各自獨立運行。
- 同步操作:多線程串行的操作碘裕,先后執(zhí)行的順序携取。
18.6.2 解決方案
- 由程序結(jié)果可知:當(dāng)兩個線程同時對同一個賬戶進行取款時,導(dǎo)致最終的賬戶余額不合理帮孔。
- 引發(fā)原因:線程一執(zhí)行取款時還沒來得及將取款后的余額寫入后臺雷滋,線程二就已經(jīng)開始取款。
- 解決方案:讓線程一執(zhí)行完畢取款操作后文兢,再讓線程二執(zhí)行即可晤斩,將線程的并發(fā)操作改為串行操作。
- 經(jīng)驗分享:在以后的開發(fā)盡量減少串行操作的范圍姆坚,從而提高效率澳泵。
18.6.3 實現(xiàn)方式
- 在Java語言中使用synchronized關(guān)鍵字來實現(xiàn)同步/對象鎖機制從而保證線程執(zhí)行的原子性,具體
方式如下:
使用同步代碼塊的方式實現(xiàn)部分代碼的鎖定兼呵,格式如下:
synchronized(類類型的引用) {
編寫所有需要鎖定的代碼兔辅;
} - 使用同步方法的方式實現(xiàn)所有代碼的鎖定。
直接使用synchronized關(guān)鍵字來修飾整個方法即可
該方式等價于:
synchronized(this) { 整個方法體的代碼 }
18.6.4 靜態(tài)方法鎖定
- 當(dāng)我們對一個靜態(tài)方法加鎖击喂,如:
public synchronized static void xxx(){….} - 那么該方法鎖的對象是類對象维苔。每個類都有唯一的一個類對象。獲取類對象的方式:類名.class茫负。
- 靜態(tài)方法與非靜態(tài)方法同時使用了synchronized后它們之間是非互斥關(guān)系的蕉鸳。
- 原因在于:靜態(tài)方法鎖的是類對象而非靜態(tài)方法鎖的是當(dāng)前方法所屬對象。
18.6.5 注意事項
- 使用synchronized保證線程同步應(yīng)當(dāng)注意:
- 多個需要同步的線程在訪問同步塊時忍法,看到的應(yīng)該是同一個鎖對象引用潮尝。
- 在使用同步塊時應(yīng)當(dāng)盡量減少同步范圍以提高并發(fā)的執(zhí)行效率。
18.6.6 線程安全和不安全類
- StringBuffer類是線程安全的類饿序,但StringBuilder類不是線程安全的類勉失。
- Vector類和 Hashtable類是線程安全的類,但ArrayList類和HashMap類不是線程安全的類原探。
- Collections.synchronizedList() 和 Collections.synchronizedMap()等方法實現(xiàn)安全乱凿。
18.6.7 死鎖
- 線程一執(zhí)行的代碼:
public void run(){
synchronized(a){ //持有對象鎖a顽素,等待對象鎖b
synchronized(b){
編寫鎖定的代碼;
}
}
} - 線程二執(zhí)行的代碼:
public void run(){
synchronized(b){ //持有對象鎖b,等待對象鎖a
synchronized(a){
編寫鎖定的代碼;
}
}
} - 注意:
在以后的開發(fā)中盡量減少同步的資源徒蟆,減少同步代碼塊的嵌套結(jié)構(gòu)的使用胁出!
18.6.8 使用鎖實現(xiàn)線程同步
-
基本概念
- 從Java5開始提供了更強大的線程同步機制—使用顯式定義的同步鎖對象來實現(xiàn)。
- java.util.concurrent.locks.Lock接口是控制多個線程對共享資源進行訪問的工具段审。
- 該接口的主要實現(xiàn)類是ReentrantLock類全蝶,該類擁有與synchronized相同的并發(fā)性,在以后的線程
安全控制中寺枉,經(jīng)常使用ReentrantLock類顯式加鎖和釋放鎖抑淫。
常用方法
方法聲明 | 功能介紹 |
---|---|
ReentrantLock() | 使用無參方式構(gòu)造對象 |
void lock() | 獲取鎖 |
void unlock() | 釋放鎖 |
-
與synchronized方式的比較
Lock是顯式鎖,需要手動實現(xiàn)開啟和關(guān)閉操作姥闪,而synchronized是隱式鎖始苇,執(zhí)行鎖定代碼后自動
釋放。Lock只有同步代碼塊方式的鎖筐喳,而synchronized有同步代碼塊方式和同步方法兩種鎖催式。
使用Lock鎖方式時,Java虛擬機將花費較少的時間來調(diào)度線程疏唾,因此性能更好蓄氧。
18.6.9 Object類常用方法
方法聲明 | 功能介紹 |
---|---|
void wait() | 用于使得線程進入等待狀態(tài),直到其它線程調(diào)用notify()或notifyAll()方法 |
void wait(long timeout) | 用于進入等待狀態(tài)槐脏,直到其它線程調(diào)用方法或參數(shù)指定的毫秒數(shù)已經(jīng)過去為止 |
void notify() | 用于喚醒等待的單個線程 |
void notifyAll() | 用于喚醒等待的所有線程 |
18.6.10 線程池
實現(xiàn)Callable接口
從Java5開始新增加創(chuàng)建線程的第三種方式為實現(xiàn)java.util.concurrent.Callable接口。
常用的方法如下:
方法聲明 | 功能介紹 |
---|---|
V call() | 計算結(jié)果并返回 |
- FutureTask類
-java.util.concurrent.FutureTask類用于描述可取消的異步計算瘾英,該類提供了Future接口的基本實
現(xiàn)懈贺,包括啟動和取消計算蜻韭、查詢計算是否完成以及檢索計算結(jié)果的方法,也可以用于獲取方法調(diào)用
后的返回結(jié)果牌废。 - 常用的方法如下:
方法聲明 | 功能介紹 |
---|---|
FutureTask(Callable callable) | 根據(jù)參數(shù)指定的引用來創(chuàng)建一個未來任務(wù) |
V get() | 獲取call方法計算的結(jié)果 |
線程池的由來
在服務(wù)器編程模型的原理,每一個客戶端連接用一個單獨的線程為之服務(wù)啤握,當(dāng)與客戶端的會話結(jié)束
時鸟缕,線程也就結(jié)束了,即每來一個客戶端連接排抬,服務(wù)器端就要創(chuàng)建一個新線程懂从。
如果訪問服務(wù)器的客戶端很多,那么服務(wù)器要不斷地創(chuàng)建和銷毀線程蹲蒲,這將嚴(yán)重影響服務(wù)器的性
能番甩。概念和原理
線程池的概念:首先創(chuàng)建一些線程,它們的集合稱為線程池届搁,當(dāng)服務(wù)器接受到一個客戶請求后缘薛,就
從線程池中取出一個空閑的線程為之服務(wù)窍育,服務(wù)完后不關(guān)閉該線程,而是將該線程還回到線程池
中宴胧。
在線程池的編程模式下漱抓,任務(wù)是提交給整個線程池,而不是直接交給某個線程恕齐,線程池在拿到任務(wù)
后乞娄,它就在內(nèi)部找有無空閑的線程,再把任務(wù)交給內(nèi)部某個空閑的線程檐迟,任務(wù)是提交給整個線程
池补胚,一個線程同時只能執(zhí)行一個任務(wù),但可以同時向一個線程池提交多個任務(wù)追迟。-
相關(guān)類和方法
從Java5開始提供了線程池的相關(guān)類和接口:java.util.concurrent.Executors類和
java.util.concurrent.ExecutorService接口溶其。方法聲明 功能介紹 static ExecutorService newCachedThreadPool() 創(chuàng)建一個可根據(jù)需要創(chuàng)建新線程的線程池 static ExecutorService newFixedThreadPool(int nThreads) 創(chuàng)建一個可重用固定線程數(shù)的線程池 static ExecutorService newSingleThreadExecutor() 創(chuàng)建一個只有一個線程的線程池 -
其中Executors是個工具類和線程池的工廠類,可以創(chuàng)建并返回不同類型的線程池敦间,常用方法如下:
方法聲明 功能介紹 void execute(Runnable command) 執(zhí)行任務(wù)和命令瓶逃,通常用于執(zhí)行Runnable Future submit(Callable task) 執(zhí)行任務(wù)和命令,通常用于執(zhí)行Callable void shutdown() 啟動有序關(guān)閉
第十九章 網(wǎng)絡(luò)編程
19.1.1 七層網(wǎng)絡(luò)模型
OSI(Open System Interconnect)廓块,即開放式系統(tǒng)互聯(lián)厢绝,是ISO(國際標(biāo)準(zhǔn)化組織)組織在1985
年研究的網(wǎng)絡(luò)互連模型。
OSI七層模型和TCP/IP五層模型的劃分如下:
當(dāng)發(fā)送數(shù)據(jù)時带猴,需要對發(fā)送的內(nèi)容按照上述七層模型進行層層加包后發(fā)送出去昔汉。
當(dāng)接收數(shù)據(jù)時,需要對接收的內(nèi)容按照上述七層模型相反的次序?qū)訉硬鸢@示出來拴清。
19.1.2 相關(guān)的協(xié)議(筆試題)
(1)協(xié)議的概念
- 計算機在網(wǎng)絡(luò)中實現(xiàn)通信就必須有一些約定或者規(guī)則靶病,這種約定和規(guī)則就叫做通信協(xié)議,通信協(xié)議
可以對速率口予、傳輸代碼娄周、代碼結(jié)構(gòu)、傳輸控制步驟沪停、出錯控制等制定統(tǒng)一的標(biāo)準(zhǔn)煤辨。
(2)TCP協(xié)議
- 傳輸控制協(xié)議(Transmission Control Protocol),是一種面向連接的協(xié)議木张,類似于打電話众辨。
- 建立連接 => 進行通信 => 斷開連接
- 在傳輸前采用"三次握手"方式。
- 在通信的整個過程中全程保持連接窟哺,形成數(shù)據(jù)傳輸通道泻轰。
- 保證了數(shù)據(jù)傳輸?shù)目煽啃院陀行蛐浴?/li>
- 是一種全雙工的字節(jié)流通信方式,可以進行大數(shù)據(jù)量的傳輸且轨。
- 傳輸完畢后需要釋放已建立的連接浮声,發(fā)送數(shù)據(jù)的效率比較低虚婿。
(3)UDP協(xié)議
- 用戶數(shù)據(jù)報協(xié)議(User Datagram Protocol),是一種非面向連接的協(xié)議泳挥,類似于寫信然痊。
- 在通信的整個過程中不需要保持連接,其實是不需要建立連接屉符。
- 不保證數(shù)據(jù)傳輸?shù)目煽啃院陀行蛐浴?/li>
- 是一種全雙工的數(shù)據(jù)報通信方式剧浸,每個數(shù)據(jù)報的大小限制在64K內(nèi)。
- 發(fā)送數(shù)據(jù)完畢后無需釋放資源矗钟,開銷小唆香,發(fā)送數(shù)據(jù)的效率比較高,速度快吨艇。
19.1.3 IP地址(重點)
192.168.1.1 - 是絕大多數(shù)路由器的登錄地址躬它,主要配置用戶名和密碼以及Mac過濾。
IP地址是互聯(lián)網(wǎng)中的唯一地址標(biāo)識东涡,本質(zhì)上是由32位二進制組成的整數(shù)冯吓,叫做IPv4,當(dāng)然也有128位二進制組成的整數(shù)疮跑,叫做IPv6组贺,目前主流的還是IPv4。
日常生活中采用點分十進制表示法來進行IP地址的描述祖娘,將每個字節(jié)的二進制轉(zhuǎn)化為一個十進制整數(shù)失尖,不同的整數(shù)之間采用小數(shù)點隔開。如:
0x01020304 => 1.2.3.4-
查看IP地址的方式:
Windows系統(tǒng):在dos窗口中使用ipconfig或ipconfig/all命令即可
Unix/linux系統(tǒng):在終端窗口中使用ifconfig或/sbin/ifconfig命令即可
特殊的地址
本地回環(huán)地址(hostAddress):127.0.0.1 主機名(hostName):localhost
19.1.4 端口號(重點)
IP地址 - 可以定位到具體某一臺設(shè)備渐苏。
端口號 - 可以定位到該設(shè)備中具體某一個進程雹仿。
端口號本質(zhì)上是16位二進制組成的整數(shù),表示范圍是:0 ~ 65535整以,其中0 ~ 1024之間的端口號通
常被系統(tǒng)占用,建議編程從1025開始使用峻仇。特殊的端口:
HTTP:80 FTP:21 Oracle:1521 MySQL:3306 Tomcat:8080網(wǎng)絡(luò)編程需要提供:IP地址 + 端口號公黑,組合在一起叫做網(wǎng)絡(luò)套接字:Socket。
19.2 基于tcp協(xié)議的編程模型(重點)
19.2.1 C/S架構(gòu)的簡介
在C/S模式下客戶向服務(wù)器發(fā)出服務(wù)請求摄咆,服務(wù)器接收請求后提供服務(wù)凡蚜。
例如:在一個酒店中,顧客找服務(wù)員點菜,服務(wù)員把點菜單通知廚師吭从,廚師按點菜單做好菜后讓服
務(wù)員端給客戶朝蜘,這就是一種C/S工作方式。如果把酒店看作一個系統(tǒng)涩金,服務(wù)員就是客戶端谱醇,廚師就
是服務(wù)器暇仲。這種系統(tǒng)分工和協(xié)同工作的方式就是C/S的工作方式。客戶端部分:為每個用戶所專有的副渴,負(fù)責(zé)執(zhí)行前臺功能奈附。
服務(wù)器部分:由多個用戶共享的信息與功能,招待后臺服務(wù)煮剧。
19.2.2 編程模型
服務(wù)器:
(1)創(chuàng)建ServerSocket類型的對象并提供端口號斥滤;
(2)等待客戶端的連接請求,調(diào)用accept()方法勉盅;
(3)使用輸入輸出流進行通信佑颇;
(4)關(guān)閉Socket;
客戶端:
(1)創(chuàng)建Socket類型的對象并提供服務(wù)器的IP地址和端口號草娜;
(2)使用輸入輸出流進行通信挑胸;
(3)關(guān)閉Socket;
19.2.3 相關(guān)類和方法的解析
(1)ServerSocket類
java.net.ServerSocket類主要用于描述服務(wù)器套接字信息(大插排)驱还。
- 常用的方法如下:
方法聲明 | 功能介紹 |
---|---|
ServerSocket(int port) | 根據(jù)參數(shù)指定的端口號來構(gòu)造對象 |
Socket accept() | 偵聽并接收到此套接字的連接請求 |
void close() | 用于關(guān)閉套接字 |
(2)Socket類
java.net.Socket類主要用于描述客戶端套接字嗜暴,是兩臺機器間通信的端點(小插排)。
- 常用的方法如下:
方法聲明 | 功能介紹 |
---|---|
Socket(String host, int port) | 根據(jù)指定主機名和端口來構(gòu)造對象 |
InputStream getInputStream() | 用于獲取當(dāng)前套接字的輸入流 |
OutputStream getOutputStream() | 用于獲取當(dāng)前套接字的輸出流 |
void close() | 用于關(guān)閉套接字 |
(3)注意事項
客戶端 Socket 與服務(wù)器端 Socket 對應(yīng), 都包含輸入和輸出流议蟆。
客戶端的socket.getInputStream() 連接于服務(wù)器socket.getOutputStream()闷沥。
客戶端的socket.getOutputStream()連接于服務(wù)器socket.getInputStream()
19.3 基于udp協(xié)議的編程模型(熟悉)
19.3.1 編程模型
接收方:
(1)創(chuàng)建DatagramSocket類型的對象并提供端口號;
(2)創(chuàng)建DatagramPacket類型的對象并提供緩沖區(qū)咐容;
(3)通過Socket接收數(shù)據(jù)內(nèi)容存放到Packet中舆逃,調(diào)用receive方法;
(4)關(guān)閉Socket戳粒;
發(fā)送方:
(1)創(chuàng)建DatagramSocket類型的對象路狮;
(2)創(chuàng)建DatagramPacket類型的對象并提供接收方的通信地址;
(3)通過Socket將Packet中的數(shù)據(jù)內(nèi)容發(fā)送出去蔚约,調(diào)用send方法奄妨;
(4)關(guān)閉Socket;
19.3.2 相關(guān)類和方法的解析
(1)DatagramSocket類
java.net.DatagramSocket類主要用于描述發(fā)送和接收數(shù)據(jù)報的套接字(郵局)苹祟。
換句話說砸抛,該類就是包裹投遞服務(wù)的發(fā)送或接收點。
- 常用的方法如下:
方法聲明 | 功能介紹 |
---|---|
DatagramSocket() | 使用無參的方式構(gòu)造對象 |
DatagramSocket(int port) | 根據(jù)參數(shù)指定的端口號來構(gòu)造對象 |
void receive(DatagramPacket p) | 用于接收數(shù)據(jù)報存放到參數(shù)指定的位置 |
void send(DatagramPacket p) | 用于將參數(shù)指定的數(shù)據(jù)報發(fā)送出去 |
void close() | 關(guān)閉Socket并釋放相關(guān)資源 |
(2)DatagramPacket類
java.net.DatagramPacket類主要用于描述數(shù)據(jù)報树枫,數(shù)據(jù)報用來實現(xiàn)無連接包裹投遞服務(wù)直焙。
- 常用的方法如下:
方法聲明 | 功能介紹 |
---|---|
DatagramPacket(byte[] buf, int length) | 根據(jù)參數(shù)指定的數(shù)組來構(gòu)造對象,用于接收長度為length的數(shù)據(jù)報 |
DatagramPacket(byte[] buf, int length,InetAddress address, int port) | 根據(jù)參數(shù)指定數(shù)組來構(gòu)造對象砂轻,將數(shù)據(jù)報發(fā)送到指定地址和端口 |
InetAddress getAddress() | 用于獲取發(fā)送方或接收方的通信地址 |
int getPort() | 用于獲取發(fā)送方或接收方的端口號 |
int getLength() | 用于獲取發(fā)送數(shù)據(jù)或接收數(shù)據(jù)的長度 |
(3)InetAddress類
java.net.InetAddress類主要用于描述互聯(lián)網(wǎng)通信地址信息奔誓。
- 常用的方法如下:
方法聲明 | 功能介紹 |
---|---|
static InetAddress getLocalHost() | 用于獲取當(dāng)前主機的通信地址 |
static InetAddress getByName(String host) | 根據(jù)參數(shù)指定的主機名獲取通信地址 |
19.4 URL類(熟悉)
19.4.1 基本概念
java.net.URL(Uniform Resource Identifier)類主要用于表示統(tǒng)一的資源定位器,也就是指向萬
維網(wǎng)上“資源”的指針搔涝。這個資源可以是簡單的文件或目錄厨喂,也可以是對復(fù)雜對象的引用和措,例如對數(shù)
據(jù)庫或搜索引擎的查詢等。
通過URL可以訪問萬維網(wǎng)上的網(wǎng)絡(luò)資源杯聚,最常見的就是www和ftp站點臼婆,瀏覽器通過解析給定的
URL可以在網(wǎng)絡(luò)上查找相應(yīng)的資源。
URL的基本結(jié)構(gòu)如下:
<傳輸協(xié)議>://<主機名>:<端口號>/<資源地址>
方法聲明 | 功能介紹 |
---|---|
URL(String spec) | 根據(jù)參數(shù)指定的字符串信息構(gòu)造對象 |
String getProtocol() | 獲取協(xié)議名稱 |
String getHost() | 獲取主機名稱 |
int getPort() | 獲取端口號 |
String getPath() | 獲取路徑信息 |
String getFile() | 獲取文件名 |
URLConnection openConnection() | 獲取URLConnection類的實例 |
方法聲明 | 功能介紹 |
---|---|
InputStream getInputStream() | 獲取輸入流 |
void disconnect() | 斷開連接 |
第二十章 反射機制
20.1 基本概念
通常情況下編寫代碼都是固定的幌绍,無論運行多少次執(zhí)行的結(jié)果也是固定的颁褂,在某些特殊場合中編寫
代碼時不確定要創(chuàng)建什么類型的對象,也不確定要調(diào)用什么樣的方法傀广,這些都希望通過運行時傳遞
的參數(shù)來決定颁独,該機制叫做動態(tài)編程技術(shù),也就是反射機制伪冰。
通俗來說誓酒,反射機制就是用于動態(tài)創(chuàng)建對象并且動態(tài)調(diào)用方法的機制。
目前主流的框架底層都是采用反射機制實現(xiàn)的贮聂。如:
Person p = new Person(); - 表示聲明Person類型的引用指向Person類型的對象
p.show(); - 表示調(diào)用Person類中的成員方法show
20.2 Class類
20.2.1 基本概念
java.lang.Class類的實例可以用于描述Java應(yīng)用程序中的類和接口靠柑,也就是一種數(shù)據(jù)類型。
該類沒有公共構(gòu)造方法吓懈,該類的實例由Java虛擬機和類加載器自動構(gòu)造完成歼冰,本質(zhì)上就是加載到內(nèi)
存中的運行時類。
20.2.2 獲取Class對象的方式
使用數(shù)據(jù)類型.class的方式可以獲取對應(yīng)類型的Class對象(掌握)耻警。
使用引用/對象.getClass()的方式可以獲取對應(yīng)類型的Class對象隔嫡。
使用包裝類.TYPE的方式可以獲取對應(yīng)基本數(shù)據(jù)類型的Class對象。
使用Class.forName()的方式來獲取參數(shù)指定類型的Class對象(掌握)甘穿。
使用類加載器ClassLoader的方式獲取指定類型的Class對象腮恩。
20.2.3 常用的方法(掌握)
方法聲明 | 功能介紹 |
---|---|
static Class<?> forName(String className) | 用于獲取參數(shù)指定類型對應(yīng)的Class對象并返回 |
T newInstance() | 用于創(chuàng)建該Class對象所表示類的新實例 |
20.3 Constructor類
20.3.1 基本概念
java.lang.reflect.Constructor類主要用于描述獲取到的構(gòu)造方法信息
20.3.2 Class類的常用方法
方法聲明 | 功能介紹 |
---|---|
Constructor getConstructor(Class<?>...parameterTypes) | 用于獲取此Class對象所表示類型中參數(shù)指定的公共構(gòu)造方法 |
Constructor<?>[] getConstructors() | 用于獲取此Class對象所表示類型中所有的公共構(gòu)造方法 |
20.3.3 Constructor類的常用方法
方法聲明 | 功能介紹 |
---|---|
T newInstance(Object...initargs) | 使用此Constructor對象描述的構(gòu)造方法來構(gòu)造Class對象代表類型的新實例 |
int getModifiers() | 獲取方法的訪問修飾符 |
String getName() | 獲取方法的名稱 |
Class<?>[] getParameterTypes() | 獲取方法所有參數(shù)的類型 |
20.4 Field類
20.4.1 基本概念
java.lang.reflect.Field類主要用于描述獲取到的單個成員變量信息。
20.4.2 Class類的常用方法
方法聲明 | 功能介紹 |
---|---|
Field getDeclaredField(String name) | 用于獲取此Class對象所表示類中參數(shù)指定的單個成員變量信息 |
Field[] getDeclaredFields() | 用于獲取此Class對象所表示類中所有成員變量信息 |
20.4.3 Field類的常用方法
方法聲明 | 功能介紹 |
---|---|
Object get(Object obj) | 獲取參數(shù)對象obj中此Field對象所表示成員變量的數(shù)值 |
void set(Object obj, Object value) | 將參數(shù)對象obj中此Field對象表示成員變量的數(shù)值修改為參數(shù)value的數(shù)值 |
void setAccessible(boolean flag) 當(dāng)實參傳遞true時温兼,則反射對象在使用時應(yīng)該取消 Java 語言訪問檢查 | |
int getModifiers() | 獲取成員變量的訪問修飾符 |
Class<?> getType() | 獲取成員變量的數(shù)據(jù)類型 |
String getName() | 獲取成員變量的名稱 |
20.5 Method類
20.5.1 基本概念
java.lang.reflect.Method類主要用于描述獲取到的單個成員方法信息秸滴。
20.5.2 Class類的常用方法
方法聲明 | 功能介紹 |
---|---|
Method getMethod(String name,Class<?>... parameterTypes) | 用于獲取該Class對象表示類中名字為name參數(shù)為parameterTypes的指定公共成員方法 |
Method[] getMethods() | 用于獲取該Class對象表示類中所有公共成員方法 |
20.5.3 Method類的常用方法
方法聲明 | 功能介紹 |
---|---|
Object invoke(Object obj,Object... args) | 使用對象obj來調(diào)用此Method對象所表示的成員方法,實參傳遞args |
int getModifiers() | 獲取方法的訪問修飾符 |
Class<?> getReturnType() | 獲取方法的返回值類型 |
String getName() | 獲取方法的名稱 |
Class<?>[] getParameterTypes() | 獲取方法所有參數(shù)的類型 |
Class<?>[] getExceptionTypes() | 獲取方法的異常信息 |
20.6 獲取其它結(jié)構(gòu)信息
方法聲明 | 功能介紹 |
---|---|
Package getPackage() | 獲取所在的包信息 |
Class<? super T> getSuperclass() | 獲取繼承的父類信息 |
Class<?>[] getInterfaces() | 獲取實現(xiàn)的所有接口 |
Annotation[] getAnnotations() | 獲取注解信息 |
Type[] getGenericInterfaces() | 獲取泛型信息 |