JavaSE核心知識

萌萌哥的春天發表於2019-07-14

一:Java簡介

           1. Java語言的介紹:Java是一門物件導向程式語言,具有功能強大和簡單易用兩個特徵。

           2. Java語言的特點:簡單性、物件導向、分散式健壯性安全性、平臺獨立與可移植性、多執行緒、動態性等

           3. Java語言的應用:編寫桌面應用程式Web應用程式分散式系統嵌入式系統應用程式等

 

二:Java自學路線圖

Java自學路線圖

 

 

 

 

 

 

 

 

三:Java基礎

    一、識別符號和關鍵字           

           1. 識別符號

                   1. 在java語言中,用來標誌類名、物件名、變數名、方法名、型別名、陣列名、包名的有效字元序列,稱為“識別符號”;

                   2. 識別符號由字母、數字、下劃線、美元符號組成,且第一個字元不能是數字;

                   3. java語言區分大小寫;

                   4. 標誌符命名規則:類名首字母大寫,變數名和方法名採用駝峰標誌法,包名全小寫,常量全大寫,多個單詞之間用“_”隔開;

           2. 關鍵字

                   1. 在java語言中,有一些專門的詞彙已經被賦予了特殊的含義,不能再使用這些詞彙來命名識別符號,這些專有詞彙,稱為“關鍵字”;

                   2. java有50個關鍵字和3個保留字,均不能用來命名識別符號;

                   3. true、false、null不是關鍵字,是保留字,但是仍不能用來命名識別符號;

    二、資料型別

資料型別

   三、運算子與表示式

           1. 算數運算子:加(+),減(-),乘(*),除(/),求餘(%)

           2. 賦值運算子:=,+=,-=,*=,%=

           3. 關係運算子:>,<,>=,<=,==,!=

           4. 邏輯運算子:[&&,||](只有左側滿足才計算右側),!,[&,|](不管左側結果如何,都要計算右側)

           5. 三目運算子:(表示式) ? 值1,值2;

    四:流程控制語句

           1. 條件分支語句:if語句,switch語句

           2. 迴圈語句:while迴圈,do while迴圈,for迴圈,foreach迴圈

 

四:陣列

         1. 宣告陣列:

                     1. 靜態初始化: 資料型別 [ ]... 陣列名 = {值1,值2,...}

                     2. 動態初始化:資料型別 [ ]... 陣列名 = new  資料型別[長度];

         2. 列印陣列:foreach迴圈

 

         3. 陣列排序:氣泡排序,選擇排序,反轉排序,插入排序

         4. Arrays工具類:

                     1. 排序

                                1. 實現Comparable介面:Arrays.sort(要排序的陣列)

                                2. 實現Comparator介面:Arrays.sort(要排序的陣列,new Comparator);

                     2. 二分法查詢:binarySearch(要查詢的陣列,要查詢的值),必須提前拍好序

                     3. 陣列元素比較:Arrays.equals(陣列1,陣列2)

                     4. 陣列填充:Arrays.fill(要填充的陣列,值)    

import java.util.Arrays;

public class TestArray {
    public static void main(String[] args) {
        // 陣列的靜態初始化
        int[] array1 = { 1, 3, 5, 6, 7, 2, 4, 10 };
        // 陣列的動態初始化
        int[] array2 = new int[5];
        array2[0] = 1;
        array2[1] = 2;
        array2[2] = 7;
        array2[3] = 3;
        array2[4] = 4;
        // for迴圈列印陣列
        for (int i = 0; i < array2.length; i++) {
            System.out.print (array2[i]);
        }
        // foreach列印陣列
        for (int i : array2) {
            System.out.print(i);
        }
        // 排序
        Arrays.sort(array2);
        for (int i : array2) {
            System.out.print(i);
        }
        // 二分法查詢
        System.out.print(Arrays.binarySearch(array2, 3));
        // 陣列元素比較
        System.out.println(Arrays.equals(array1, array2));
        // 陣列元素填充
        Arrays.fill(array2, 1);
        for (int j : array2) {
            System.out.println(j);
        }
    }
}
陣列程式碼實現

 

五:物件導向

         一、封裝

                   1. 核心思想:隱藏細節,保護資料安全。

                 2. 訪問許可權

                

public class Encapsulation {
    // 1.成員屬性私有化
    private String name;
    private String pwd;

    // 2.提供getter和setter方法來訪問
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
}

class TestEncapsulation {
    public static void main(String[] args) {
        Encapsulation test = new Encapsulation();
        // 3.通過setter方法設定屬性值
        test.setName("封裝");
        test.setPwd("666");
        // 4.通過getter方法獲取值
        System.out.println("姓名:" + test.getName() + " -- 密碼:" + test.getPwd());

    }
}
封裝程式碼實現

 

         二、方法的過載和重寫

               1. 方法的過載:方法名相同,引數列表不同

                 2. 方法的重寫:方法名、返回值型別、引數列表都相同,構造方法和使用final、static修飾的方法不能被重寫

 

         三、繼承    

                   1. 核心思想:解決程式碼冗餘,提高程式碼的複用性

                 2. 繼承關係:滿足is-a的關係,父類更通用,子類更具體。

/**
 * 1. 將類中重複的部分提取成為父類
 */
public class Animal {
    private String name;
    private String food;

    public Animal(String name, String food) {
        this.name = name;
        this.food = food;
    }

    public void eat() {
        System.out.println(name + "正在吃" + food);
    }
}

/**
 * 2. 子類繼承父類,對父類進行擴充套件
 */
public class Cat extends Animal {

    public Cat(String name, String food) {
        super(name, food);
    }
}
public class Dog extends Animal{

    public Dog(String name, String food) {
        super(name, food);
    }
}

/**
 * 3. 測試
 */
public class TestExtends{
    public static void main(String[] args) {
        Animal cat = new Cat("三三", "魚");
        cat.eat();
        Animal dog = new Dog("二哈", "香腸");
        cat.eat();
    }
}
繼承程式碼實現

 

           四、多型

                 1. 核心思想:提高程式碼可維護性和可擴充套件性

                 2. 實現多型的三個必要條件:繼承、重寫、父類引用指向子類物件(向下轉型)

                 3. 多型的實現方式:重寫、介面、抽象類和抽象方法

 

/**
 * 1. 建立動物類,定義動物吃什麼的方法
 */
class Animals {
    private String name;
    private String food;
    
    public Animals(String name, String food) {
        super();
        this.name = name;
        this.food = food;
    }

    public void eat() {
        System.out.println(this.name + "會吃" + this.food);
    }
}


/**
 * 2. 建立Cat類來實現吃的功能
 */
class Cat extends Animals{
    public Cat(String name, String food) {
        super(name, food);
    }

    @Override
    public void eat() {
        super.eat();
    }
}


/**
 * 3. 通過向上轉型和向下轉型實現多型
 */
public class Test01 {
    public static void main(String[] args) {
        // 向下轉型
        Animals animals = new Cat("三三", "魚");
        animals.eat();
        // 向上轉型
        Cat cat = (Cat) animals;
        cat.eat();
    }
}
多型程式碼實現

 

         五、抽象類

                 1. 核心思想:讓程式碼有更強的可擴充套件性

                 2. 特點:

                            1. 抽象類不能例項化物件。

                            2. 如果一個類包含抽象方法,那麼該類必須是抽象類。

                                3. 任何子類必須重寫父類的抽象方法(具體實現),或者宣告自身為抽象類。

                            4. 抽象類中的抽象方法只有方法宣告,沒有方法體

                            5. 構造方法和static修飾的方法不能宣告為抽象方法

/**
 * 1. 建立員工抽象類
 */
abstract class Employees {
    // 成員變數
    private String name;
    private String address;
    private Integer number;

    // 構造方法
    public Employees(String name, String address, Integer number) {
        System.out.println("Employees.Employees()");
        this.name = name;
        this.address = address;
        this.number = number;
    }

    // 定義資訊抽象函式
    public abstract void call();

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public Integer getNumber() {
        return number;
    }

    public void setNumber(Integer number) {
        this.number = number;
    }
}

class Salary extends Employees {
    private Double salary;

    public Salary(String name, String address, Integer number, Double salary) {
        super(name, address, number);
        this.salary = salary;
        System.out.println("Salary.Salary()");
    }

    // 2. 重寫父類的抽象方法
    @Override
    public void call() {
        System.out.println(super.getNumber() + "是" + super.getName() + "的電話,他住在" + 
        super.getAddress() + "他現在的工資是" + this.salary);
    }
}

public class Test {
    public static void main(String[] args) {
        // 3. 抽象類的物件必須由子類去例項化
        Employees emp = new Salary("孫悟空", "花果山", 1234, 222.66);
        emp.call();
    }
}
抽象類程式碼實現

 

         六、介面      

                 1. 核心思想:讓程式碼有更強的可擴充套件性

                 2. 特點:

                            1. 介面不能例項化物件,沒有構造方法

                            2. 介面中的方法只能是抽象方法,預設使用public abstract修飾

                                3. 介面中的變數只能是常量,預設使用public static final修飾

                                4. 介面支援多繼承,但介面不是被繼承了,而是被實現了

                3. 介面和抽象類的區別

                            1. 介面中的方法只能是抽象方法,而抽象類中的方法可以是普通方法,構造方法和抽象方法

                            2. 介面中的變數只能是常量,而抽象類中的方法可以是任意型別

                                3. 介面中不能含有靜態程式碼塊和靜態方法,而抽象類中可以有

                                4. 一個類可以實現多個介面,但一個類只能繼承一個抽象類

/**
 * 1. 建立Animal介面
 */
interface Animal {
    // 定義睡覺抽象方法
    void sleep();

    // 定義吃飯抽象方法
    void eat();
}

/**
 * 2. 建立Dog介面繼承Animal介面
 */
interface Dog extends Animal {
    // 定義游泳抽象方法
    void swim();
}

/**
 * 3. 建立HaShiQi介面繼承Dog和Animal介面,實現多繼承
 */
interface HaShiQi extends Dog, Animal {
    // 定義拆家抽象方法
    void demolishedFamily();
}

/**
 * 4. 建立測試類來實現介面,並且複寫所有抽象方法
 */
public class TestAnimal implements HaShiQi {

    @Override
    public void swim() {
        System.out.println("哈士奇會游泳");
    }

    @Override
    public void sleep() {
        System.out.println("哈士奇會睡覺");
    }

    @Override
    public void eat() {
        System.out.println("哈士奇喜歡吃苦瓜");
    }

    @Override
    public void demolishedFamily() {
        System.out.println("哈士奇會拆家");
    }

    public static void main(String[] args) {
        // 使用多型例項化物件
        HaShiQi dog = new TestAnimal();
        dog.eat();
        dog.sleep();
        dog.demolishedFamily();
        dog.swim();
    }

}
介面實現程式碼

 

六:集合

      一、集合簡介

                 集合的主要作用是儲存引用型別資料,長度可以動態的改變,解決了儲存資料數量不確定的問題

 

      二、Collection集合體系

              Collection集合體系

                  

                 一、Collection常用方法

                             Collection常用方法

                二、不同集合的使用場景

                                 不同集合使用場景

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * 建立學生類
 */
class Student {
    // 學號
    private Integer id;
    // 姓名
    private String name;

    public Student(Integer id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public String toString() {
        return "Student [id=" + id + ", name=" + name + "]";
    }

}

public class TestCollection {
    public static void main(String[] args) {
        // 1. 建立集合儲存String型別資料
        List<String> list = new ArrayList<String>();

        // 2.向集合中新增元素
        list.add("豬豬俠");
        list.add("超人強");
        list.add("波比");
        list.add("小菲菲");

        // 3. 遍歷集合
        // 3.1普通for迴圈
        String[] strArray = new String[list.size()];
        list.toArray(strArray); // 將集合轉換為陣列
        for (int i = 0; i < strArray.length; i++) {
            System.out.println(strArray[i]);
        }

        // 3.2 foreach迴圈
        for (String str : list) {
            System.out.println(str);
        }

        // 3.3 迭代器遍歷
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) { // hasNext():判斷指標後是否有下一個元素
            System.out.println(iterator.next()); // next():返回指標後的元素
        }

        // 4. 判斷集合中是否包含某元素
        System.out.println(list.contains("小菲菲")); // true

        // 5. 判斷集合是否為空
        System.out.println(list.isEmpty()); // false

        // 6. 清除集合中所有元素
        list.clear();
        System.out.println(list.isEmpty()); // true
        System.out.println("---------------------------------------------------");

        
        // 建立集合儲存物件型別資料
        List<Student> list2 = new ArrayList<Student>();

        // 向集合中新增物件型別資料
        list2.add(new Student(1, "張三"));
        list2.add(new Student(2, "李四"));

        // foreach遍歷集合
        for (Student student : list2) {
            System.out.println(student);
        }

        // 迭代器遍歷集合
        Iterator<Student> iterator2 = list2.iterator();
        while (iterator2.hasNext()) {
            Student student = iterator2.next();
            System.out.println(student);
        }
    }
}
Collection集合程式碼實現

 

      三、Map集合體系

               Map集合體系

                Map集合常用方法

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import javax.enterprise.inject.New;

class Teacher {
    private String name;
    private Integer age;

    public Teacher(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Teacher [name=" + name + ", age=" + age + "]";
    }

}

public class TestMap {
    public static void main(String[] args) {
        // 1. 建立Map集合儲存學號和姓名
        Map<Integer, String> map = new HashMap<Integer, String>();

        // 2. 向map集合中新增元素
        map.put(1, "張三");
        map.put(2, "李四");
        map.put(3, "王五");

        // 3. 遍歷map集合
        // 3.1 通過map.keySet()遍歷集合
        for (Integer key : map.keySet()) {
            System.out.println("key=" + key + " value=" + map.get(key));
        }

        // 3.2 通過迭代器遍歷集合
        Iterator<Entry<Integer, String>> iterator = map.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<Integer, String> entry = iterator.next();
            System.out.println("key=" + entry.getKey() + " value=" + entry.getValue());
        }

        // 3.3 通過map.entrySet()遍歷集合
        for (Entry<Integer, String> entry : map.entrySet()) {
            System.out.println("key=" + entry.getKey() + " value=" + entry.getValue());
        }

        // 4. 判斷集合中是否包含指定鍵
        System.out.println(map.containsKey("1")); // true
        System.out.println(map.containsValue("list")); // false

        // 5. 判斷集合是否為空
        System.out.println(map.isEmpty()); // false

        // 6. 清除集合中所有元素
        map.clear();
        System.out.println(map.isEmpty()); // true
        System.out.println("----------------------------------------");

        
        // 1. 建立Map集合儲存物件型別資料
        Map<Integer, Teacher> map2 = new HashMap<Integer, Teacher>();

        // 2. 向Map集合中新增物件型別資料
        map2.put(1, new Teacher("張三", 18));
        map2.put(2, new Teacher("李四", 19));
        map2.put(3, new Teacher("王五", 20));

        // 3. 遍歷集合
        // 3.1 通過map.keySet()遍歷
        for (Integer key : map2.keySet()) {
            System.out.println("key=" + key + " value=" + map2.get(key));
        }

        // 3.2 通過迭代器遍歷集合
        Iterator<Entry<Integer, Teacher>> iterator2 = map2.entrySet().iterator();
        while (iterator2.hasNext()) {
            Entry<Integer, Teacher> entry = iterator2.next();
            System.out.println("key=" + entry.getKey() + " value=" + entry.getValue());
        }

        // 3.3 通過map.entrySet()遍歷集合
        for (Entry<Integer, Teacher> entry : map2.entrySet()) {
            System.out.println("key=" + entry.getKey() + " value=" + entry.getValue());
        }
    }
}
Map集合程式碼實現

 

七:IO流

           一、IO流簡介

                           1. 流的概念:流是有起點和終點的一組有順序的位元組集合,作用是進行資料傳輸

                        2. 流的分類:

                                         1. 按照資料流向不同可以分為輸入輸出流;

                                         2. 按照處理資料單位不同可以分為位元組流和字元流

                        3. 輸入流和輸出流的作用

                                         1. 輸入流:程式從資料來源讀取資料

                                         2. 輸出流:將資料從程式中寫入指定檔案

                        4. 位元組流和字元流的作用

                                        1. 位元組流:以位元組為單位處理所有型別資料                                        

                                              2. 字元流:以字元為單位處理純文字檔案

 

           二、IO流體系

                IO流

 

             三、IO流常用方法

                  IO流常用方法

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

/**
 * 1. 文字檔案複製
 * @author DELL
 *
 */
public class TestIO {
    public static void main(String[] args) {
        // 要讀取的檔案
        String src = "E:/Workspaces1/Demo/src/TestFile.java";
        // 要寫入的檔案
        String dest = "d:/test.java";

        // 1.1 一次複製一個位元組
        copyFile1(src, dest);
        // 1.2 一次複製一個位元組陣列
        copyFile2(src, dest);
        
        // 2.1 一次複製一個字元
        copyFile3(src, dest);
        // 2.2 一次複製一個字元陣列
        copyFile4(src, dest);
    }

    // 1. 一次複製一個位元組,異常處理,手動關閉流
    public static void copyFile1(String srcFileName, String destFileName) {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream(srcFileName);
            fos = new FileOutputStream(destFileName);
            int cc = fis.read();
            while (cc != -1) {
                // 一次寫入一個位元組
                fos.write(cc);
                // 一次寫入一個位元組
                cc = fis.read();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    // 2. 一次複製一個位元組陣列,異常處理,自動關閉流
    public static void copyFile2(String srcFileName, String destFileName) {
        // 自動關閉流
        try (
                FileInputStream fis = new FileInputStream(srcFileName);
                FileOutputStream fos = new FileOutputStream(destFileName);
                ) {
            byte[] bytes = new byte[1024];
            int len = fis.read(bytes);
            while (len != -1) {
                // 一次寫入一個位元組陣列
                fos.write(bytes, 0, len);
                // 一次讀取一個位元組陣列
                len = fis.read(bytes);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 3. 一次複製一個字元,異常處理,自動關閉流
    public static void copyFile3(String srcFileName, String destFileName) {
        try (
                FileReader fr = new FileReader(srcFileName);
                FileWriter fw = new FileWriter(destFileName);
                ){
            int cc = fr.read();
            while (cc != -1) {
                // 一次寫入一個字元
                fw.write(cc);
                // 一次讀取一個字元
                cc = fr.read();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
        
    // 4. 一次複製一個字元陣列,異常處理,手動關閉流
    public static void copyFile4(String srcFileName, String destFileName) {
        FileReader fr = null;
        FileWriter fw = null;
        try {
            fr = new FileReader(srcFileName);
            fw = new FileWriter(destFileName);
            char[] cbuf = new char[1024];
            int len = fr.read(cbuf);
            while (len != -1) {
                // 一次寫入一個字元陣列
                fw.write(cbuf);
                // 一次讀取一個字元陣列
                len = fr.read(cbuf);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fw != null) {
                try {
                    fw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fr != null) {
                try {
                    fr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
文字檔案複製程式碼實現

 

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

/**
 * 1. 序列化和反序列化的概念 
 *          1. 物件序列化:把物件轉換為位元組序列(二進位制資料)的過程 
 *          2. 物件反序列化:把位元組序列恢復為物件的過程
 * 
 * 2. 什麼情況下需要序列化: 
 *          1. 將物件儲存到檔案或資料庫中時 
 *          2. 使用套接字在網上傳送物件時 
 *          3. 通過RMI傳輸物件時
 * 
 * 3. 如何實現序列化 
 *          1. 建立類實現Serializable介面
 *          2. 指定serialVersionUID序列號 
 *          3. 使用物件輸出流(ObjectOutputStream)將物件儲存到指定位置
 *          4. 使用writerObject()方法將物件寫入到檔案中
 *          
 * 
 * 4. 哪些屬性不能被序列化
 *          1. 使用transient修飾的屬性
 *          2. 使用static修飾的屬性
 *          
 */

// 1. 建立類實現Serializable介面
class People implements Serializable {

    // 2. 指定序列號
    private static final long serialVersionUID = 1L;
    // 靜態欄位
    private static String id = "2019";
    // transient關鍵字修飾的欄位
    private transient String name;
    
    private Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "People [name=" + name + ", age=" + age + "]";
    }

}

public class Test {
    public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
        serializePeople();
        deserializePeople();
    }
    
    /**
      * 序列化
     */
    public static void serializePeople() throws FileNotFoundException, IOException {
        People p = new People();
        p.setName("張三");
        p.setAge(18);
        // 3. 使用物件輸出流將物件儲存到指定位置
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("D:/test.txt")));
        // 4. 將物件寫入檔案
        oos.writeObject(p);
        System.out.println("物件序列化成功!!");
        oos.close();
    }
    
    /**
      * 反序列化
     */
    public static People deserializePeople() throws ClassNotFoundException, IOException {
        // 使用物件輸入流從指定位置讀取物件
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("D:/test.txt")));
        // 讀取物件
        People p = (People) ois.readObject();
        System.out.println("物件反序列化成功!!");
        return p;
        
    }
}
序列化和反序列化總結及程式碼實現

 

            四、File類常用方法      

                      

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.text.SimpleDateFormat;

public class TestFile {
    public static void main(String[] args) throws IOException {
        // 1. 構造方法指明檔案路徑以及格式
        File file = new File("D:\\test2\\test.txt");
        File file2 = new File("D:\\test2");
        File file3 = new File("D:\\test3");
        
        // 2.1 建立一個檔案
        file.createNewFile();
        // 2.2 建立一個單級目錄
        file2.mkdir();
        // 2.3 建立一個多級目錄
        file3.mkdirs();
        
        // 3.1 判斷檔案或資料夾是否存在
        System.out.println(file.exists()); // true
        // 3.2 判斷是否為絕對路徑
        System.out.println(file.isAbsolute()); // true
        // 3.3 判斷是否為檔案
        System.out.println(file2.isFile()); // false
        // 3.4 判斷是否為目錄
        System.out.println(file2.isDirectory()); // true
        // 3.5 判斷是否為隱藏檔案
        System.out.println(file3.isHidden()); // false
        
        // 4.1 獲取檔案或目錄名稱
        System.out.println(file.getName());
        // 4.2 獲取檔案的絕對路徑
        System.out.println(file.getAbsolutePath());
        // 4.3 獲取檔案相對路徑
        System.out.println(file.getPath());
        // 4.4 獲取檔案父目錄
        System.out.println(file.getParent());
        // 4.5 獲取檔案大小
        System.out.println(file.length());
        // 4.6 獲取檔案最後一次被修改時間
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String updateTime = sdf.format(file.lastModified());
        System.out.println(updateTime);
        
        // 5.1 返回此目錄下的所有檔案和目錄
        String [] fileString = file2.list();
        for (String str : fileString) {
            System.out.println(str);
        }
        // 5.2 返回此目錄下的所有檔案
        File [] files = file2.listFiles();
        for (File file4 : files) {
            System.out.println(file4.getName());
        }
        // 5.3  返回所有根目錄
        File [] files2 = File.listRoots();
        for (File file4 : files2) {
            System.out.println(file4);
        }
        // 5.4 返回指定目錄中符合過濾條件的檔案和目錄
        File [] files3 = file2.listFiles(new FileFilter() {
            
            @Override
            public boolean accept(File pathname) {
                while ("a.txt".equals(pathname.getName())){
                    return true;
                }
                return false;
            }
        });
        for (File file4 : files3) {
            System.out.println(file4.getName());
        }
    }
}
File類程式碼實現

 

八:多執行緒

            一、執行緒相關概念

                        1. 執行緒和程式

                                        1. 程式:作業系統中的應用程式,一個程式就是一個應用程式

                                        2. 執行緒:CPU排程的最小單元,程式的一個執行流

                          2. 上下文切換           

                                        1. 上下文切換:CPU從一個執行緒或程式切換到另一個程式或執行緒;

                                        2. 多執行緒程式並不是同時進行的,由於CPU的執行速度太快,CPU會在不同的執行緒之間快速的切換執行;

 

            二、多執行緒的三種實現方式及優缺點

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

/**
 * 1. 建立多執行緒的三種方式
 *        1. 繼承Thread類
 *        
 *        2. 實現Runnable介面 
 *             1. 方式一:建立類實現Runnable介面
 *                    1. 建立類實現Runnable介面
 *                    2. 重寫run()方法
 *                    3. 使用Thread類的構造方法例項化實現Runnable介面的類物件
 *                    4. 開啟執行緒
 *              
 *             2. 方式二:使用匿名內部類
 *                    1. 使用Thread類的構造方法建立一個Runnable介面的代理物件
 *                    2. 重寫run()方法
 *                    2. 開啟執行緒
 *                    
 *        3. 實現Callable介面
 *              1. 方式一:建立類實現Callable介面
 *                     1. 建立類實現Callable介面
 *                     2. 重寫call()方法
 *                     3. 使用Thread類的構造方法例項化FutureTask物件
 *                     4. 使用FutureTask類的構造方法例項化實現了Callable介面的類物件
 *                     5. 開啟執行緒
 *              
 *              2. 方式二:使用匿名內部類
 *                     1. 使用Thread類的構造方法例項化FutureTask物件
 *                     2. 使用FutureTask類的構造方法建立Callable介面的代理物件
 *                     3. 重寫call()方法
 *                     4. 開啟執行緒
 *                     
 * 2. 三種方式的優缺點
 *        1. 繼承了Thread類
 *             1. 優點:程式碼書寫簡單
 *             2. 缺點:由於Java的單繼承性,程式碼的耦合度比較高
 *             
 *        2. 實現了Runnable介面和Callable介面
 *             1. 方式一: 
 *                 1. 優點:程式碼的可擴充套件性更強
 *                 2. 缺點:沒有缺點
 *                 
 *             2. 方式二:
 *                 1. 優點:程式碼書寫簡單
 *                 2. 缺點:只適合執行緒使用一次的時候
 */                 


/**
 * 1. 繼承Thread類
 */
class Thread1 extends Thread{
    public static void test() {
        for (int i = 0; i < 100; i++) {
            System.out.println("繼承Thread類執行的第" + i + "次");
        }
    }
}

/**
 * 2. 實現Runnable介面
 */
class Thread2 implements Runnable{

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("實現Runnable介面方式一執行的第" + i + "次");
        }
    }
}

/**
 * 3. 實現Callable介面
 */
class Thread3 implements Callable<Integer>{
    @Override
    public Integer call() throws Exception {
        int i = 0;
        for (; i < 100; i++) {
            System.out.println("實現Callable介面方式一執行的第" + i + "次");
        }
        return i;
    }
}

public class TestThread {
    public static void main(String[] args) {
        // 1. 測試繼承Thread類
        Thread1 thread1 = new Thread1();
        thread1.start();
        Thread1.test();
        
        
        // 2. 測試實現Runnable介面
        // 2.1 方式一
        new Thread(new Thread2()).start();
        
        // 2.2 方式二
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    System.out.println("實現Runnable介面方式一執行的第" + i + "次");
                }
            }
        }).start();
        
        
        // 3. 測試實現Callable介面
        // 3.1 方式一
        new Thread(new FutureTask<Integer>(new Thread3() {
        }), "方式三").start();;
        
        // 3.2 方式二
        new Thread(new FutureTask<Integer>(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                int i = 0;
                for (; i < 100; i++) {
                    System.out.println("實現Runnable介面方式二執行的第" + i + "次");
                }
                return i;
            }
        })).start();;
    }
}
多執行緒的三種實現方式及優缺點

 

            三、多執行緒常用方法  

                           

public class TestThreadMethod {
    public static void main(String[] args) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    // 獲取正在執行的執行緒物件的引用
                    System.out.println(Thread.currentThread().getName() + "執行的第" + i + "次");
                }
            }
        });
        // 1. 開啟執行緒
        thread.start();
        
        
        // 2. 設定
        // 2.1 設定該執行緒名稱
        thread.setName("執行緒1號");
        // 2.2 設定該執行緒為守護執行緒:main方法結束之後該執行緒停止
        //thread.setDaemon(true);
        // 2.3 設定該執行緒的優先順序
        thread.setPriority(7);
        
        
        // 3. 獲取
        // 3.1 獲取執行緒名稱
        System.out.println(thread.getName()); // 執行緒1號
        // 3.2 獲取執行緒識別符號
        System.out.println(thread.getId()); // 13
        // 3.3 獲取執行緒優先順序
        System.out.println(thread.getPriority()); // 7
        // 3.4 獲取執行緒狀態
        System.out.println(thread.getState()); // RUNNABLE
        // 3.5 獲取執行緒所線上程組
        System.out.println(thread.getThreadGroup()); // java.lang.ThreadGroup[name=main,maxpri=10]
        
        
        // 4. 判斷
        // 4.1 判斷執行緒是否中斷
        System.out.println(thread.isInterrupted()); // false
        // 4.2 判斷執行緒是否為活動狀態
        System.out.println(thread.isAlive()); // true
        // 4.3 判斷執行緒是否為守護執行緒
        System.out.println(thread.isDaemon()); // false
        
        
        // 5. 停
        // 5.1 讓執行緒休眠指定毫秒數
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 50; i++) {
                    System.out.println(Thread.currentThread().getName() + "執行的第" + i + "次");
                    if (i == 25) {
                        try {
                            /**
                             * 1. sleep()是靜態方法
                             * 2. sleep()使用時必須捕獲異常
                             * 3. sleep()執行時,只是讓該執行緒進入阻塞狀態,並不會釋放鎖
                             */
                            System.out.println("執行緒2號正在休眠");
                            Thread.sleep(5000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        },"執行緒2號").start();
        
        // 5.2 暫停當前執行緒去執行其他執行緒
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 50; i++) {
                    System.out.println(Thread.currentThread().getName() + "執行了" + i + "次");
                    if (i == 25) {
                        /**
                         * 1. yield()是靜態方法
                         * 2. yield()執行時,讓執行緒進入就緒狀態,重新爭搶CPU執行權,並不會釋放鎖
                         */
                        Thread.yield();
                    }
                }
            }
        },"執行緒3號").start();
        
        // 5.3 等待執行緒銷燬
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    if (i == 50) {
                        /**
                         * 1. join()是物件方法
                         * 2. join()使用時必須捕獲異常
                         * 3. join()使用場景:一個執行完的執行緒需要另一個正在執行的執行緒的執行結果時
                         */
                        System.out.println("執行緒1號正在銷燬!!!!");
                        try {
                            thread.join();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("執行緒1號銷燬成功!!!!");
                    }
                }
            }
        },"執行緒4號").start();
        
    }
}
多執行緒常用方法程式碼實現

                       

               四、執行緒同步

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


/**
 * 1. 執行緒安全
 *         1. 什麼是執行緒安全:當多個執行緒同時操作同一共享資料時,導致共享資料出錯
 *         2. 怎樣解決:使用執行緒同步技術
 *         
 * 2. 執行緒同步:將多個執行緒的資料共享
 * 
 * 3. 實現執行緒同步的方式
 *         1. 同步程式碼塊:有synchronized關鍵字修飾的語句塊
 *                1. 例項程式碼塊:鎖物件是this或者任意物件
 *                2. 靜態程式碼塊:鎖物件是當前類的位元組碼檔案
 *                
 *         2. 同步方法: 有synchronized關鍵字修飾的方法
 *                1. 例項方法
 *                2. 靜態方法
 *                
 *         3. 使用重入鎖
 *                1. 宣告鎖物件
 *                2. 給共享資料上鎖
 *                3. 在finally中解鎖
 *                
 *         4. wait()和notify()
 *                 wait(): 執行緒等待,釋放鎖
 *                 notify(): 喚醒等待狀態執行緒
 */

class Bank{
    // 例項賬戶
    private Integer account1 = 100;
    // 靜態賬戶
    private static  Integer account2 = 100;
    // 1. 宣告鎖物件
    private Lock lock = new ReentrantLock();
    
    
    
    /**
     * 1. 同步程式碼塊
     */
    // 存錢1
    public  void save1(Integer money) {
        // 例項程式碼塊
        synchronized (this) {
            account1 += money;
        }
        System.out.println(Thread.currentThread().getName() + "存入了" + money + "元");
    }
    // 取錢1
    public  void draw1(Integer money) {
        // 例項程式碼塊
        synchronized (this) {
            if (account1 - money < 0) {
                System.out.println("賬戶餘額不足");
                return;
            }
            account1 -= money;
            System.out.println(Thread.currentThread().getName() + "取出了" + money + "元");
        }
    }
    // 存錢2
    public static void save2(Integer money) {
        // 靜態程式碼塊
        synchronized (Bank.class) {
            account2 += money;
        }
        System.out.println(Thread.currentThread().getName() + "存入了" + money + "元");
    }
    // 取錢2
    public static void draw2(Integer money) {
        // 靜態程式碼塊
        synchronized (Bank.class) {
            if (account2 - money < 0) {
                System.out.println("餘額不足");
                return;
            }
            account2 -= money;
            System.out.println(Thread.currentThread().getName() + "取出了" + money + "元");
        }
    }
    
    /**
     * 2. 同步方法
     */
    // 2.1 例項方法
    public synchronized void save3(Integer money) {
        account1 += money;
        System.out.println(Thread.currentThread().getName() + "存入了" + money + "元");
    }
    public synchronized void draw3(Integer money) {
        if (account1 - money < 0) {
            System.out.println("餘額不足");
            return;
        }
        account1 -= money;
        System.out.println(Thread.currentThread().getName() + "取出了" + money + "元");
    }
    
    // 2.2 靜態方法
    public synchronized static void save4(Integer money) {
        account2 += money;
        System.out.println(Thread.currentThread().getName() + "存入了" + money + "元");
    }
    public synchronized static void draw4(Integer money) {
        if (account2 - money < 0) {
            System.out.println("餘額不足");
            return;
        }
        account2 -= money;
        System.out.println(Thread.currentThread().getName() + "取出了" + money + "元");
    }
    
    
    /**
     * 3. 重入鎖
     */
    public void save5(Integer money) {
        // 2. 上鎖
        lock.lock();
        try {
            account1 += money;
            System.out.println(Thread.currentThread().getName() + "存入了" + money + "元");
        } finally {
            // 3. 解鎖
            lock.unlock();
        }
    }
    public  void draw5(Integer money) {
        // 2. 上鎖
        lock.lock();
        try {
            if (account1 - money < 0) {
                System.out.println("餘額不足");
                return;
            }
            account1 -= money;
            System.out.println(Thread.currentThread().getName() + "取出了" + money + "元");
        } finally {
            // 3. 解鎖
            lock.unlock();
        }
    }
    
    // 檢視賬戶餘額
    public void show() {
        System.out.println("例項賬戶餘額" + account1);
        System.out.println("靜態賬戶餘額" + account2);
    }
    
}

class Demo implements Runnable{
    private static Bank bank = new Bank();
    @Override
    public void run() {
        /**
         * 1. 測試同步程式碼塊
         */
        // 1.1 例項程式碼塊
        bank.save1(100);
        bank.show();
        bank.draw1(20);
        bank.show();
        
        // 1.2 靜態程式碼塊
        Bank.save2(100);
        bank.show();
        Bank.draw2(20);
        bank.show();
        
        /**
         * 2. 測試同步方法
         */
        // 2.1 例項方法
        bank.save3(100);
        bank.show();
        bank.draw3(20);
        bank.show();
        // 2.2 靜態方法
        Bank.save4(100);
        bank.show();
        Bank.draw4(20);
        bank.show();
        
        /**
         * 3. 測試重入鎖
         */
        bank.save5(100);
        bank.show();
        bank.draw5(20);
        bank.show();
    }        
}

public class TestSynchronized {
    public static void main(String[] args) {
        // 1. 測試同步例項程式碼塊
        new Thread(new Demo(),"執行緒1號").start();
        // 2. 測試同步靜態程式碼塊
        new Thread(new Demo(),"執行緒2號").start();
        
        // 2. 測試同步方法
        // 2.1 例項方法
        new Thread(new Demo(),"執行緒3號").start();
        // 2.2 靜態方法
        new Thread(new Demo(),"執行緒4號").start();
        
        // 3. 測試衝入鎖
        new Thread(new Demo(),"執行緒5號").start();
        
    }
}
執行緒同步總結及程式碼實現

 

               五、執行緒控制(執行緒狀態轉換圖)

 

                            執行緒狀態轉換圖    

 

 

九:網路程式設計

                一、網路程式設計概述

                          1. 計算機網路:多臺算機之間實現資訊傳遞和資源共享的的計算機系統

                             2. 網路程式設計:不同計算機之間使用網路進行資料交換

 

             二、網路程式設計三要素

                          1.  IP:每個裝置在網路中的唯一標識

                             2. 埠號:每個程式在裝置上的唯一標識

                             3. 協議:在網路中進行資料交換要遵守的規則

 

             三、 UDP與TCP的區別

                           1. UDP:面向無連線,資料不可靠,速度快,適用於高速傳輸和對實時性要求較高

                              2. TCP:面向連線,資料可靠,速度略低,適用於可靠傳輸

            

             四、網路程式設計常用方法

                          網路程式設計常用方法

          

            五、UDP傳輸 

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

/**
 * 1. 伺服器端實現步驟
 *       1. 建立伺服器物件 
 *       2. 將接受到的資料打包
 *       3. 將資料包儲存到伺服器物件
 *       4. 列印資料
 *       5. 關閉流通道
 *      
 * 2. 客戶端步驟實現
 *       1. 建立客戶端物件
 *       2. 將資料打包
 *       3. 傳送資料包
 *       4. 關閉流通道
 *       
 * @author 萌萌哥的春天
 *
 */


/**
 * 伺服器端
 */
public class Server {
    public static void main(String[] args) throws IOException {
        // 1. 建立伺服器物件
        DatagramSocket ds = new DatagramSocket(9102);
        
        // 2. 將接收到的資料打包
        byte[] bytes = new byte[1024];
        DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
        
        // 3. 將資料包存入伺服器物件
        ds.receive(dp);
        
        // 4. 列印資料
        String IP = dp.getAddress().getHostAddress(); // IP地址
        int port = dp.getPort();
        String data = new String(dp.getData(), 0, dp.getLength()); // 將位元組陣列轉為字串
        System.out.println(IP+": --" + data + "--" + port + ":");
        
        // 5. 關閉流通道
        ds.close();
    }
}

/**
 * 客戶端
 */
public class Client {
    public static void main(String[] args) throws IOException {
        // 1. 建立客戶端物件
        DatagramSocket ds = new DatagramSocket();
        
        // 2. 將資料打包
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); // 接受鍵盤輸入
        byte[] bytes = br.toString().getBytes(); // 將字串轉換為位元組陣列
        DatagramPacket dp = new DatagramPacket(bytes, bytes.length, InetAddress.getByName("localhost"),9102);
        
        // 3. 傳送資料包
        ds.send(dp);
        
        // 4. 關閉流通道
        ds.close();
    }
}
UDP傳輸程式碼實現

 

             六、TCP傳輸

/**
 * 1. 伺服器端實現步驟
 *       1. 建立伺服器物件 
 *       2. 偵聽客戶端連線
 *       3. 使用輸入流讀取客戶端輸入
 *       4. 使用輸出流寫入檔案
 *       5. 使用輸出流通知客戶端
 *       6. 關閉流通道
 *       
 * 2. 客戶端步驟實現
 *       1. 建立客戶端物件
 *       2. 使用輸出流傳送資料到伺服器
 *       3. 使用輸入流讀取本地檔案
 *       4. 使用輸入流接收伺服器反饋並列印到控制檯
 *       5. 關閉流通道
 *       
 * @author 萌萌哥的春天
 *
 */

import java.io.BufferedWriter;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;


/**
 * 伺服器端
 */
public class Server {
    private static ServerSocket server;
    private static Socket socket;
    private static InputStream in;
    private static OutputStream out;

    public static void main(String[] args) {
        try {
            // 1. 建立伺服器物件
            server = new ServerSocket(9102);

            // 2. 偵聽客戶端連線
            socket = server.accept();

            // 3. 使用輸入流接收客戶端輸入
            in = socket.getInputStream();

            // 4. 使用輸出流寫入檔案
            out = new FileOutputStream("D:/server.txt");
            byte[] bytes = new byte[1024];
            int len = 0;
            while ((len = in.read(bytes)) != -1) {
                out.write(bytes, 0, len);
                out.flush();
            }

            // 5. 使用輸出流通知客戶端
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            bw.write("檔案上傳成功");
            bw.flush();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 6. 關閉流通道
            if (server != null) {
                try {
                    server.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

/**
  * 客戶端
  */
public class Client {
    private static Socket socket;
    private static InputStream in;
    
    public static void main(String[] args) {
        try {
            // 1. 建立客戶端物件
            socket = new Socket("localhost", 9102);

            // 2. 使用輸入流傳送資料到伺服器
            OutputStream out = socket.getOutputStream();

            // 3. 使用輸入流讀取本地檔案
            in = new FileInputStream("D:/client.txt");
            byte[] bytes = new byte[1024];
            int len = 0;
            while ((len = in.read(bytes)) != -1) {
                out.write(bytes, 0, len);
            }
            
            // 4. 通知伺服器檔案已上傳
            socket.shutdownOutput();
            
            // 5. 使用輸出流接收伺服器反饋
            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            System.out.println(br.readLine());
            
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 6. 關閉流通道
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
TCP傳輸程式碼實現

 

 十:反射

             一、反射概述

                           1. 反射機制:動態獲取類的資訊和呼叫物件的方法的功能

                           2. 反射實現:獲取每個類的位元組碼檔案,也就是Class類物件

            

             二、反射的三種方式

/**
 * 反射的三種方式:推薦2和3
 *      1. Object類的getClass()方法 
 *      2. 實體類.class 
 *      3. Class類的forName()方法
 */


public class TestReflect {
    public static void main(String[] args) {
        // 1. 方式一:getClass()方法
        Worker worker = new Worker();
        Class<? extends Worker> class1 = worker.getClass();
        System.out.println(class1.getName()); // Worker
        
        // 2. 方式二:實體類.class
        Class<Worker> class2 = Worker.class;
        System.out.println(class1 == class2); // true
        
        // 3. 方式三:Class類的forName()方法
        try {
            Class<?> class3 = Class.forName("Worker");
            System.out.println(class2 == class3); // true
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}
反射的三種方法

 

             三、Class常用方法

                           

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

class Worker {
    // 私有屬性
    private Integer id;
    private String name;
    // 公共屬性
    Integer age;

    public Worker() {
    }

    public Worker(String name) {
        this.name = name;
    }

    protected Worker(Integer id, String name) {
        this.id = id;
        this.name = name;
    }

    private Worker(Integer id, String name, Integer age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    // 繼承方法
    @Override
    public String toString() {
        return "Worker [id=" + id + ", name=" + name + ", age=" + age + "]";
    }

    // 私有方法
    private void test() {
        System.out.println("這是私有方法");
    }

}

public class TestReflect {
    public static void main(String[] args) {
        // 1. 建立Class物件
        Class<Worker> class1 = Worker.class;
        Class<String> class2 = String.class;
        
        
        /**
         *  2. 類相關操作
         */
        
        // 2.1 獲取完整性類名
        System.out.println(class2.getName()); // java.lang.String
        
        // 2.2 獲取類名
        System.out.println(class2.getSimpleName()); // String
        
        // 2.3 獲取此類的包名
        System.out.println(class2.getPackage()); // package java.lang
        
        // 2.4 獲取當前類所繼承父類的名字
        System.out.println(class2.getSuperclass()); // class java.lang.Object
        
        // 2.5獲取當前類實現的介面
        Class<?>[] interfaces = class2.getInterfaces();
        for (Class<?> class3 : interfaces) {
            System.out.println(class3); 
            // interface java.io.Serializable
            // interface java.lang.Comparable
            // interface java.lang.CharSequence
        }    
        
        
        /**
         * 3. 類中屬性相關操作
         */
        
        // 3.1 獲取指定屬性
        try {
            Field declaredField = class1.getDeclaredField("name");
            System.out.println(declaredField); // private java.lang.String Worker.name
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        }
        
        // 3.2 獲取所有屬性
        Field[] declaredFields = class1.getDeclaredFields();
        for (Field field : declaredFields) {
            System.out.println(field);
            // private java.lang.Integer Worker.id
            // private java.lang.String Worker.name
            // java.lang.Integer Worker.age
        }
        
        
        /**
         * 4. 類中構造方法相關操作
         */
        
        // 4.1 獲取引數列表匹配的構造方法
        try {
            Constructor<Worker> declaredConstructor = class1.getDeclaredConstructor(Integer.class, String.class, Integer.class);
            System.out.println(declaredConstructor); // private Worker(java.lang.Integer,java.lang.String,java.lang.Integer)
            System.out.println(class1.getDeclaredConstructor(String.class)); // public Worker(java.lang.String)
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        }
        
        // 4.2 獲取類中所有公共構造方法
        Constructor<?>[] constructors = class1.getConstructors();
        for (Constructor<?> constructor : constructors) {
            System.out.println(constructor);
            // public Worker(java.lang.String)
            // public Worker()
        }
        
        // 4.3 獲取類中所有構造方法
        Constructor<?>[] declaredConstructors = class1.getDeclaredConstructors();
        for (Constructor<?> constructor : declaredConstructors) {
            System.out.println(constructor);
            // private Worker(java.lang.Integer,java.lang.String,java.lang.Integer)
            // protected Worker(java.lang.Integer,java.lang.String)
            // public Worker(java.lang.String)
            // public Worker()
        }
        
        /**
         * 5. 類中方法相關操作
         */
        
        // 5.1 獲取方法名和引數列表都匹配的方法
        try {
            Method declaredMethod = class1.getDeclaredMethod("toString");
            System.out.println(declaredMethod); // public java.lang.String Worker.toString()
            System.out.println(class1.getDeclaredMethod("test")); // //private void Worker.test()
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        }
        
        // 5.2 獲取類中所有公共方法
        Method[] methods = class1.getMethods();
        for (Method method : methods) {
            System.out.println(method); // 當前類方法和它所繼承的類及其實現的介面中的所有公共方法
        }
        
        // 5.3 獲取當前類中所有方法
        Method[] declaredMethods = class1.getDeclaredMethods();
        for (Method method : declaredMethods) {
            System.out.println(method);
            // public java.lang.String Worker.toString()
            // private void Worker.test()
        }
        
    }
}
Class類常用方法程式碼實現

 

             四、反射核心操作

import java.lang.reflect.Field;
import java.lang.reflect.Method;

class Worker {
    // 私有屬性
    private Integer id;
    private String name;
    // 公共屬性
    public Integer age;

    public Worker() {
    }

    @Override
    public String toString() {
        return "Worker [id=" + id + ", name=" + name + ", age=" + age + "]";
    }

    // 私有方法
    private void test() {
        System.out.println("這是私有方法");
    }
    
    // 公共方法
    public void show() {
        System.out.println("這是公共方法");
    }
}

public class TestReflect {
    public static void main(String[] args) throws Exception {
        // 1. 建立Class物件
        Class<?> class1 = Class.forName("Worker");
        
        // 2. 通過構造方法例項化類物件
        Object obj = class1.getConstructor().newInstance();
        
        // 3. 給公共屬性設定值
        Field field1 = class1.getField("age");
        field1.set(obj, 18);
        
        // 4. 給私有屬性設定值
        Field field = class1.getDeclaredField("name");
        field.setAccessible(true); // 解除私有限定
        field.set(obj, "張三"); // 為Worker類中的name屬性設定值
        
        // 5. 呼叫公共成員方法
        Method method1 = class1.getMethod("show");
        method1.invoke(obj);
        
        // 6. 呼叫私有成員方法
        Method method = class1.getDeclaredMethod("test");
        method.setAccessible(true);
        method.invoke(obj); // 第一個引數是類物件,其餘的為實參
        System.out.println(obj);
    }
}
反射核心操作程式碼實現

 

相關文章