JavaSE核心知識

一:Java簡介html

           1. Java語言的介紹:Java是一門面向對象編程語言,具備功能強大和簡單易用兩個特徵。前端

           2. Java語言的特色:簡單性、面向對象、分佈式健壯性安全性、平臺獨立與可移植性、多線程、動態性等java

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

 

二:Java自學路線圖數據庫

                  Java自學路線圖

 

三:Java基礎
編程

    1、標識符和關鍵字           
數組

           1. 標識符安全

                   1. 在java語言中,用來標誌類名、對象名、變量名、方法名、類型名、數組名、包名的有效字符序列,稱爲「標識符」;服務器

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

                   3. java語言區分大小寫;

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

           2. 關鍵字

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

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

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

 

    2、數據類型

 

 

 

                    數據類型

 

    3、運算符與表達式

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

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

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

           4. 邏輯運算符:[&&,||](只有左側知足才計算右側),!,[&,|](無論左側結果如何,都要計算右側)

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

 

    4、流程控制語句

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

           2. 循環語句:while循環,do while循環,for循環,foreach循環

 

四:數組

        1、數組概述

                 1. 數組的概念:相同數據類型元素的集合

                   2. 數組的做用:用來存儲基本數據類型和引用數據類型的數據

 

        2、數組的建立及排序                  

public class TestArray {
    public static void main(String[] args) {
        /**
         * 1. 數組的初始化
         */
        // 1.1 數組的靜態初始化
        int[] array1 = { 1, 3, 5, 6, 7, 2, 4, 10 };

        // 1.2 數組的動態初始化
        int[] array2 = new int[5];
        array2[0] = 1;
        array2[1] = 2;
        array2[2] = 7;
        array2[3] = 3;
        array2[4] = 4;

        /**
         * 2. 數組的遍歷
         */
        // 2.1 for循環打印數組
        for (int i = 0; i < array2.length; i++) {
            System.out.print(array2[i]);
        }

        // 2.2 foreach打印數組
        for (int i : array2) {
            System.out.print(i);
        }

        /**
         * 3. 數組排序
         */

        // 3.1 冒泡排序
        for (int i = 0; i < array2.length; i++) {
            for (int j = i + 1; j < array2.length; j++) {
                // 1. 比較相鄰元素,將較大的數冒泡
                if (array2[i] > array2[j]) {
                    // 2. 交換
                    int temp = array2[i];
                    array2[i] = array2[j];
                    array2[j] = temp;
                }
            }
        }
        for (int i : array2) {
            System.out.println(i);
        }

        // 3.2 選擇排序
        for (int i = 0; i < array2.length; i++) {
            int min = i;
            for (int j = i; j < array2.length; j++) {
                // 1. 找到最小的數
                if (array2[j] < array2[min]) {
                    // 2. 將最小的數賦值給min
                    min = j;
                }
            }
            // 3. 交換兩個數的位置
            int temp = array2[i];
            array2[i] = array2[min];
            array2[min] = temp;
        }
        for (int i : array2) {
            System.out.println(i);
        }

        // 3.3 反轉排序
        for (int i = 0; i < array2.length / 2; i++) {
            // 將第i位元素與array2.length-1-i位元素交換
            int temp = array2[i];
            array2[i] = array2[array2.length - 1 - i];
            array2[array2.length - 1 - i] = temp;
        }
        for (int i : array2) {
            System.out.println(i);
        }

        // 3.4 插入排序
        for (int i = 0; i < array2.length; i++) {
            int j = i;
            int tmp = array2[i];
            for (; j > 0 && tmp < array2[j - 1]; j--) {
                // 1. 將大於待排序的數向後移
                array2[j] = array2[j - 1];
            }
            // 2. 交換
            array2[j] = tmp;
        }
        for (int i : array2) {
            System.out.println(i);
        }
        }
}
數組的初始化及排序代碼實現

 

        3、Arrays工具類經常使用方法

import java.util.Arrays;

public class TestArray {
    public static void main(String[] args) {
        int[] array1 = { 1, 3, 5, 2, 4 };
        int[] array2 = {3,2};
        
        // 1. 排序
        Arrays.sort(array2);
        for (int i : array2) {
            System.out.print(i);
        }
        
        // 2. 二分法查找
        System.out.print(Arrays.binarySearch(array2, 3));
        
        // 3. 數組元素比較
        System.out.println(Arrays.equals(array1, array2));
        
        // 4. 數組元素填充
        Arrays.fill(array2, 1);
        for (int j : array2) {
            System.out.println(j);
        }

    }
}
Arrays工具類經常使用方法代碼實現

 

五:面向對象

         1、封裝

                   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());

    }
}
封裝代碼實現

 

         2、方法的重載和重寫

               1. 方法的重載:方法名相同,參數列表不一樣

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

 

         3、繼承    

                   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();
    }
}
繼承代碼實現

 

           4、多態

                 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();
    }
}
多態代碼實現

 

         5、抽象類

                 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();
    }
}
抽象類代碼實現

 

         6、接口      

                 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();
    }

}
接口實現代碼

 

六:集合

      1、集合簡介

                 集合的主要做用是存儲引用類型數據,長度能夠動態的改變,解決了存儲數據數量不肯定的問題

 

      2、Collection集合體系

              Collection集合體系

                  

                 1、Collection經常使用方法

                             Collection經常使用方法

                2、不一樣集合的使用場景

                                 不一樣集合使用場景

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集合代碼實現

 

      3、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流

           1、IO流簡介

                           1. 流的概念:流是有起點和終點的一組有順序的字節集合,做用是進行數據傳輸

                        2. 流的分類:

                                         1. 按照數據流向不一樣能夠分爲輸入輸出流;

                                         2. 按照處理數據單位不一樣能夠分爲字節流和字符流

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

                                         1. 輸入流:程序從數據源讀取數據

                                         2. 輸出流:將數據從程序中寫入指定文件

                        4. 字節流和字符流的做用

                                        1. 字節流:以字節爲單位處理全部類型數據                                        

                                              2. 字符流:以字符爲單位處理純文本文件

 

           2、IO流體系

                IO流

 

             3、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;
        
    }
}
序列化和反序列化總結及代碼實現

 

            4、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. 線程和進程

                                        1. 進程:操做系統中的應用程序,一個進程就是一個應用程序

                                        2. 線程:CPU調度的最小單元,進程的一個執行流

                          2. 上下文切換           

                                        1. 上下文切換:CPU從一個線程或進程切換到另外一個進程或線程;

                                        2. 多線程程序並非同時進行的,因爲CPU的執行速度太快,CPU會在不一樣的線程之間快速的切換執行;

 

            2、多線程的三種實現方式及優缺點

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();;
    }
}
多線程的三種實現方式及優缺點

 

            3、多線程經常使用方法  

                           

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();
        
    }
}
多線程經常使用方法代碼實現

                       

               4、線程同步

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();
        
    }
}
線程同步總結及代碼實現

 

               5、線程控制(線程狀態轉換圖)

 

                            線程狀態轉換圖    

 

 

九:網絡編程

                1、網絡編程概述

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

                             2. 網絡編程:不一樣計算機之間使用網絡進行數據交換

 

             2、網絡編程三要素

                          1.  IP:每一個設備在網絡中的惟一標識

                             2. 端口號:每一個程序在設備上的惟一標識

                             3. 協議:在網絡中進行數據交換要遵照的規則

 

             3、 UDP與TCP的區別

                           1. UDP:面向無鏈接,數據不可靠,速度快,適用於高速傳輸和對實時性要求較高

                              2. TCP:面向鏈接,數據可靠,速度略低,適用於可靠傳輸

            

             4、網絡編程經常使用方法

                          網絡編程經常使用方法

          

            5、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傳輸代碼實現

 

             6、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、反射概述

                           1. 反射機制:動態獲取類的信息和調用對象的方法的功能

                           2. 反射實現:獲取每一個類的字節碼文件,也就是Class類對象

            

             2、反射的三種方式

/**
 * 反射的三種方式:推薦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();
        }
    }
}
反射的三種方法

 

             3、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類經常使用方法代碼實現

 

             4、反射核心操做

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);
    }
}
反射核心操做代碼實現

 

第二階段:web前端

相關文章
相關標籤/搜索