- Junit介紹 (***** 瞭解 *****)
Java Unit Java單元測試框架java
Junit是Java語言編寫單元測試框架,最直觀的理解,就是取代java類中的main方法。Junit屬於第三方工具,通常狀況下須要導入jar包,而多數Java開發環境都集成了Junit。程序員
Junit的使用數組
建立「MyJunit」java項目,並建立「cn.itcast.junit」包數據結構
- 編寫測試類,簡單理解Junit能夠用於取代java的main方法
- 在測試類方法上添加註解 @Test
- @Test修飾的方法要求:public void 方法名() {…} ,方法名自定義建議test開頭,沒有參數。
- 添加Eclipse中集成的Junit庫,鼠標點擊「@Test」,使用快捷鍵「ctrl + 1」,點擊「Add Junit …」
結果框架
- 使用:選中方法右鍵,執行當前方法;選中類名右鍵,執行類中全部方法(方法必須標記@Test)
- 經常使用註解
@Test,用於修飾須要執行的方法ide
@Before,測試方法前執行的方法工具
@After,測試方法後執行的方法單元測試
- import org.junit.After;
- import org.junit.Before;
- import org.junit.Test;
-
- public class JunitDemo {
- @Before
- public void test_Before() {
- System.out.println("Before 註解的方法 ...");
- }
-
- @After
- public void test_After() {
- System.out.println("After 註解的方法 ...");
- }
-
- @Test
- public void test_01() {
- System.out.println("測試 test01 方法 ...");
- }
-
- @Test
- public void test_02() {
- System.out.println("測試 test02 方法 ...");
- }
-
- @Test
- public void test_03() {
- System.out.println("測試 test03 方法 ...");
- }
- }
- 常見使用錯誤,若是沒有添加「@Test」,使用「Junit Test」進行運行,將拋異常
- 類加載器 (***** 瞭解 *****)
類加載器:類加載器是負責加載類的對象。將class文件(硬盤)加載到內存生成Class對象。測試
全部的類加載器 都是 java.lang.ClassLoader 的子類ui
類的加載說明 :
類的加載指的是將類的.class文件中的二進制數據讀入到內存中,將其放在運行時數據區的方法區內,而後在堆區建立一個 java.lang.Class對象,用來封裝類在方法區內的數據結構.
注意 : 只有Java虛擬機才能建立class類的對象.
重點 : 類加載的最終產品是位於堆區中的 Class對象.
Class對象封裝了類在方法區內的數據結構 ,而且向Java程序員提供了訪問方法區內的數據結構的接口,這些接口都定義在了 `反射` 包中.
- 引導類加載器
- package cn.itcast.classloader;
-
- import java.util.Properties;
-
- import org.junit.Test;
-
- public class ClassLoaderDemo01 {
-
- @Test
- public void demo01() {
- // 肯定引導類加載器類型: null
- ClassLoader cl = String.class.getClassLoader();
- System.out.println(cl);
- }
- }
2. 擴展類加載器
- package cn.itcast.classloader;
-
- import org.junit.Test;
-
- import sun.net.spi.nameservice.dns.DNSNameService;
-
- public class ClassLoaderDemo02 {
-
- @Test
- public void demo01() {
- // 添加項目訪問規則 -> Properties -> BuildPath -> Library
- // -> JRE System -> Access rules -> Edit -> add -> sun/**
-
- // 肯定擴展類加載器類型: Launcher$ExtClassLoader
- ClassLoader cl = DNSNameService.class.getClassLoader();
- System.out.println(cl);
- }
- }
3. 應用類加載器
- package cn.itcast.classloader;
-
- import org.junit.Test;
-
- import sun.net.spi.nameservice.dns.DNSNameService;
-
- public class ClassLoaderDemo03 {
-
- @Test
- public void demo03() {
- // 肯定應用類加載器類型: Launcher$AppClassLoader
- ClassLoader cl = ClassLoaderDemo03.class.getClassLoader();
- System.out.println(cl);
- }
- }
4. 類加載器之間的關係
- package cn.itcast.classloader;
-
- import org.junit.Test;
-
- public class ClassLoaderDemo04 {
- @Test
- public void demo01() {
- // 驗證三個類加載器之間的關係:
- ClassLoader cl1 = ClassLoaderDemo04.class.getClassLoader();
- System.out.println(cl1); // AppClassLoader
-
- ClassLoader cl2 = cl1.getParent();
- System.out.println(cl2); // ExtClassLoader
-
- ClassLoader cl3 = cl2.getParent();
- System.out.println(cl3); // null
- }
- }
- 反射詳解 (***** 瞭解 *****)
反射概述 :
Java反射機制是在運行狀態中,對指定的類,任意的方法或任意的字段進行操做,這種動態獲取的信息以及動態調用對象方法的功能稱爲java語言的反射機制。
簡而言之,反射就是:在運行時經過代碼操做類。
想要操做類,就必須先得到該類的字節碼對象Class 對象。經過Class提供的方法對類進行進一步的解剖,從而實現各類操做。
在進行具體操做以前,你們須要先掌握類各個組成的專業描述
Class類
Constructor 構造方法
Method 方法
Field 字段 / 屬性
instance 實例 / 實例對象
invoke 調用, 執行
- 三種獲取Class對象的方式
- /*
- * 不一樣的應用場景, 須要使用不一樣的方式獲取 Class 對象.
- *
- * 1. 經過字符串 (全限定名) 得到. `包名 + 類名`
- * 格式 : Class cls = Class.forName("字符串");
- * 場景 : 開發中, 從配置文件中獲取 `全限定類名`, 並經過反射進行全部操做.
- *
- * 2. 經過 Java 類型獲取.
- * 格式 : Class cls = 類名.class;
- * 場景 : 肯定方法形參列表時, 須要經過類型得到.
- * 例如 : public void init(String s, int i) {}
- * 類型對應的Class參數列表爲: init(String.class, int.class);
- *
- * 3. 經過實例對象得到.
- * 格式 : Class cls = obj.getClass();
- * 場景 : 方法內部經過變量名(實例對象名)得到.
- * 例如 : public void init(Object obj) {
- * obj.getClass();
- * }
- */
- public class ClassDemo {
- @Test
- public void demo01() throws ClassNotFoundException {
- Class<?> cls = Class.forName("cn.itcast.practice.ClassDemo");
- System.out.println(cls);
- }
-
- @Test
- public void demo02() {
- Class<?> cls = String.class;
- System.out.println(cls);
- }
-
- @Test
- public void demo03() {
- Object obj = new String();
- Class<?> cls = obj.getClass();
- System.out.println(cls);
- }
- }
- 供一個 Student類, 用於以後的反射操做
- package cn.itcast.reflect;
-
- // 提供 Student 類, 用於以後的反射操做.
- public class Student {
-
- public static void main(String[] args) {
- System.out.println("Student 類的 main 方法被調用... ");
- System.out.println("args[0]=" + args[0] + ", args[1]=" + args[1]);
- }
- // 屬性
- private String name;
- private int age;
-
- public String description;
- // 無參構造方法
- public Student() {
- System.out.println("無參構造方法被調用...");
- }
-
- public Student(String name, int age) {
- System.out.println("帶 String name, int age 參數的構造方法被調用...");
- this.name = name;
- this.age = age;
- }
-
- // 私有構造方法
- private Student(String name, int age, String description) {
- System.out.println("私有構造方法被調用...");
- this.name = name;
- this.age = age;
- this.description = description;
- }
- // 私有方法
- private void show(int num) {
- System.out.println("私有方法: " + num);
- }
-
- public String getDescription() {
- return description;
- }
- public void setDescription(String description) {
- this.description = description;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
-
- @Override
- public String toString() {
- return "Student [name=" + name + ", age=" + age + ", description=" + description + "]";
- }
- }
- 使用反射調用構造方法建立對象
- package cn.itcast.reflect;
-
- import java.lang.reflect.Constructor;
-
- import org.junit.Test;
-
- public class ConstructorDemo {
- // 普通方式 : 直接 new 對象.
- @Test
- public void demo01() {
- // 觸發 `無參構造方法`
- // Student stu = new Student();
-
- // 觸發 `有參構造方法`
- // Student stu = new Student("Jack", 30);
-
- // 觸發 `私有構造方法` 錯誤!
- // Student stu = new Student("Jack", 30, "學霸");
- // System.out.println(stu);
- }
-
- // 經過反射調用無參構造方法得到實例對象
- @Test
- public void demo02() throws Exception {
- // 1. 獲取Class對象
- Class<?> cls = Class.forName("cn.itcast.reflect.Student");
- // 2. 經過cls直接建立對象, 至關於: new Student();
- Object obj = cls.newInstance();
- }
-
- // 經過反射調用有參構造方法, 得到實例對象
- @Test
- public void demo03() throws Exception {
- // 1. 獲取Class對象
- Class<?> cls = Class.forName("cn.itcast.reflect.Student");
- // 2. 得到構造方法, 至關於: Student(String name, int age);
- // getConstructor(Class<?>... parameterTypes)
- Constructor<?> cons = cls.getConstructor(new Class[]{String.class, int.class});
- // 3. 調用構造方法, 得到實例對象, 至關於: new Student();
- // newInstance(Object ... initargs)
- Object obj = cons.newInstance(new Object[]{"Jack", 30});
- System.out.println(obj);
- }
-
- // 經過私有構造方法得到實例對象
- @Test
- public void demo04() throws Exception {
- // 1. 獲取 Class 對象
- Class<?> cls = Class.forName("cn.itcast.reflect.Student");
- // 2. 獲取構造方法
- Constructor<?> cons = cls.getDeclaredConstructor(new Class[]{String.class, int.class, String.class});
- // 暴力訪問 (默認不容許)
- cons.setAccessible(true);
- // 3. 調用構造方法, 得到實例對象
- Object obj = cons.newInstance(new Object[]{"Jack", 30, "學霸"});
- System.out.println(obj);
- }
- }
- 使用反射執行方法
- package cn.itcast.reflect;
-
- import java.lang.reflect.Method;
-
- import org.junit.Test;
-
- public class MethodDemo {
- @Test
- public void demo01() {
- Student stu = new Student();
- stu.setName("Jack");
- stu.setAge(30);
- System.out.println(stu);
-
- String name = stu.getName();
- int age = stu.getAge();
- System.out.println("name: " + name + ", age: " + age);
-
- // stu.show(); 錯誤! 沒法調用私有方法.
- }
-
- @Test
- public void demo02() throws Exception {
- // 1. 得到實例
- Class<?> cls = Class.forName("cn.itcast.reflect.Student");
- Object obj = cls.newInstance();
-
- // 2.1 獲取 setName(String name) 方法
- Method setNameMethod = cls.getMethod("setName", String.class);
- // 2.2 調用方法, 傳遞實際參數
- setNameMethod.invoke(obj, "Jack");
- // 2.3 獲取 setAge(int age) 方法
- Method setAgeMethod = cls.getMethod("setAge", int.class);
- // 2.4 調用
- setAgeMethod.invoke(obj, 30);
-
- System.out.println(obj);
-
- // Method getNameMethod = cls.getMethod("getName", null);
- // Object name = getNameMethod.invoke(obj, null);
- // Method getAgeMethod = cls.getMethod("getAge", null);
- // Object age = getAgeMethod.invoke(obj, null);
- Method getNameMethod = cls.getMethod("getName");
- Object name = getNameMethod.invoke(obj);
- Method getAgeMethod = cls.getMethod("getAge");
- Object age = getAgeMethod.invoke(obj);
- System.out.println("name: " + name + ", age: " + age);
- }
-
- @Test
- public void demo03() throws Exception {
- // 1. 得到實例
- Class<?> cls = Class.forName("cn.itcast.reflect.Student");
- Object obj = cls.newInstance();
-
- // 2. 獲取方法並調用執行
- Method showMethod = cls.getDeclaredMethod("show", int.class);
- showMethod.setAccessible(true); // 暴力訪問
- Object result = showMethod.invoke(obj, 100);
-
- // 若是方法沒有返回結果, 那麼結果爲 null
- System.out.println(result);
- }
-
- // 執行靜態方法 main, 無需得到實例, 可是必需要得到 Class 對象
- @Test
- public void demo04() throws Exception {
- // 1. 得到 Class 對象
- Class<?> cls = Class.forName("cn.itcast.reflect.Student");
-
- // 2. 得到 main 方法
- Method mainMethod = cls.getMethod("main", new Class[]{String[].class});
- // 特色注意 : 數組類型的參數書寫格式
- mainMethod.invoke(null, new Object[]{new String[]{"Hello", "World"}});
- }
- }
可變參數的方法調用方式 :
- 使用反射獲取屬性
- package cn.itcast.reflect;
-
- import java.lang.reflect.Field;
-
- import org.junit.Test;
-
- public class FieldDemo {
- @Test
- public void demo01() {
- Student stu = new Student();
- stu.description = "描述信息";
- System.out.println(stu);
- }
-
- @Test
- public void demo02() throws Exception {
- // 1. 得到實例
- Class<?> cls = Class.forName("cn.itcast.reflect.Student");
- Object obj = cls.newInstance();
-
- // 2. 得到屬性
- Field descField = cls.getField("description");
- descField.set(obj, "描述信息: 學霸");
-
- System.out.println(obj);
- }
-
- @Test
- public void demo03() throws Exception {
- // 1. 得到實例
- Class<?> cls = Class.forName("cn.itcast.reflect.Student");
- Object obj = cls.newInstance();
-
- // 2. 得到屬性並設置數值
- Field nameField = cls.getDeclaredField("name");
- nameField.setAccessible(true);
- nameField.set(obj, "Jack");
- Field ageField = cls.getDeclaredField("age");
- ageField.setAccessible(true);
- ageField.set(obj, 30);
-
- System.out.println(obj);
-
- // 查看屬性
- Object name = nameField.get(obj);
- Object age = ageField.get(obj);
- System.out.println("name: " + name + ", age: " + age);
- }
- }
- 反射綜合案例 – 舉辦晚會 (***** 練習 *****)
party.properties
- #singable=cn.itcast.classloader.LiuDeHua
- #dancable=cn.itcast.classloader.GirlsTeam
- #performable=cn.itcast.classloader.LiuQian
-
- singable=cn.itcast.classloader.ZhangXueYou
- dancable=cn.itcast.classloader.GirlsGeneration
- performable=cn.itcast.classloader.ZhaoBenShan
Dancable
- package cn.itcast.classloader;
-
- public interface Dancable {
- void dance();
- }
Singable
- package cn.itcast.classloader;
-
- public interface Singable {
- void sing();
- }
Performable
- package cn.itcast.classloader;
-
- public interface Performable {
- void perform();
- }
PartyFactory
- package cn.itcast.classloader;
-
- import java.io.FileReader;
- import java.io.IOException;
- import java.util.Properties;
-
- public class PartyFactory {
-
- private static Properties prop = new Properties();
-
- static {
- try {
- prop.load(new FileReader("party.properties"));
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- public static Singable getSingable() throws Exception {
- String className = prop.getProperty("singable");
- Class<?> cls = Class.forName(className);
- return (Singable) cls.newInstance();
- }
-
- public static Dancable getDanceble() throws Exception {
- String className = prop.getProperty("dancable");
- Class<?> cls = Class.forName(className);
- return (Dancable) cls.newInstance();
- }
-
- public static Performable getPerformable() throws Exception {
- String className = prop.getProperty("performable");
- Class<?> cls = Class.forName(className);
- return (Performable) cls.newInstance();
- }
- }
EveningParty
- package cn.itcast.classloader;
-
- public class EveningPartyDemo {
- public static void main(String[] args) throws Exception {
-
- System.out.println("晚會開始了...");
-
- // 歌曲
- Singable singable = PartyFactory.getSingable();
- singable.sing();
-
- // 舞蹈
- Dancable danceble = PartyFactory.getDanceble();
- danceble.dance();
-
- // 表演
- Performable performable = PartyFactory.getPerformable();
- performable.perform();
-
- System.out.println("難忘今宵!");
- }
- }
ZhangXueYou
- package cn.itcast.classloader;
-
- public class ZhangXueYou implements Singable {
- @Override
- public void sing() {
- System.out.println("張學友 演唱 `一路上有你`!");
- }
- }
GirlsGeneration
- package cn.itcast.classloader;
-
- public class GirlsGeneration implements Dancable {
- @Override
- public void dance() {
- System.out.println("少女時代 跳 Gee Gee Gee!");
- }
- }
ZhaoBenShan
- package cn.itcast.classloader;
-
- public class ZhaoBenShan implements Performable {
- @Override
- public void perform() {
- System.out.println("趙本山 表演 `賣柺`!");
- }
- }
LiuDeHua
- package cn.itcast.classloader;
-
- public class LiuDeHua implements Singable {
- @Override
- public void sing() {
- System.out.println("劉德華 演唱 `愛你一萬年`!");
- }
- }
GirlsTeam
- package cn.itcast.classloader;
-
- public class GirlsTeam implements Dancable {
- @Override
- public void dance() {
- System.out.println("女子團隊 跳 `性感廣場舞`!");
- }
- }
LiuQian
- package cn.itcast.classloader;
-
- public class LiuQian implements Performable {
- @Override
- public void perform() {
- System.out.println("劉謙 表演 `大變活人`!");
- }
- }