JAVA入門(mén)筆記~基礎(chǔ)知識(shí)day17

單元測(cè)試

1. 前言

  1. 單元測(cè)試是指程序員寫(xiě)的測(cè)試代碼給自己的類中的方法進(jìn)行預(yù)期正確性的驗(yàn)證。
  2. 單元測(cè)試一旦寫(xiě)好了這些測(cè)試代碼,就可以一直使用,可以實(shí)現(xiàn)一定程度上的自動(dòng)化測(cè)試。
  3. 單元測(cè)試一般要使用框架進(jìn)行。

1.1 什么是框架?

  1. 框架是前人或者一些牛逼的技術(shù)公司在實(shí)戰(zhàn)或者研發(fā)中設(shè)計(jì)的一些優(yōu)良的設(shè)計(jì)方案或者成型的
    代碼功能,作為一個(gè)完整的技術(shù)體系發(fā)行出來(lái)稱為框架。

  2. 框架可以讓程序員快速擁有一個(gè)強(qiáng)大的解決方案,可以快速的開(kāi)發(fā)功能,提高效率并且直接就有了很好的性能。

  3. 單元測(cè)試的經(jīng)典框架:Junit

1.2 Junit是什么

  1. Junit是Java語(yǔ)言編寫(xiě)的第三方單元測(cè)試框架(工具類)
  2. Junit框架的方案可以幫助我們方便且快速的測(cè)試我們的代碼的正確性。
    Junit單元測(cè)試框架的作用
  3. 用來(lái)對(duì)類中的方法功能進(jìn)行有目的的測(cè)試,以保證程序的正確性和穩(wěn)定性。
  4. 能夠獨(dú)立的測(cè)試某個(gè)方法或者所有方法的預(yù)期正確性。

1.3 Junit注解

  1. @Before // 修飾實(shí)例方法。在每個(gè)單元測(cè)試方法執(zhí)行之前執(zhí)行一次
  2. @After // 修飾實(shí)例方法。在每個(gè)單元測(cè)試方法執(zhí)行之后執(zhí)行一次
  3. @BeforeClass // 修飾靜態(tài)方法。在每個(gè)單元測(cè)試方法執(zhí)行之前執(zhí)行一次
  4. @AfterClass // 修飾靜態(tài)方法。在每個(gè)單元測(cè)試方法執(zhí)行之后執(zhí)行一次
  5. @Test

2. 概述

  1. 單元:在Java中,一個(gè)類就是一個(gè)單元
  2. 單元測(cè)試:程序猿用Junit編寫(xiě)的一小段代碼,用來(lái)對(duì)某個(gè)類中的某個(gè)方法進(jìn)行功能測(cè)試或業(yè)務(wù)邏輯測(cè)試。

3. 操作步驟

3.1 下載這個(gè)框架。(別人設(shè)計(jì)好的技術(shù)體系)

  1. 框架一般是jar包的形式,jar包里面都是class文件。
    1. class文件就是我們調(diào)用的核心代碼。
  2. Junit已經(jīng)被IDEA下載好了,可以直接導(dǎo)入到項(xiàng)目使用的。

3.2 直接用Junit測(cè)試代碼即可

  1. 先模擬業(yè)務(wù)代碼

  2. 寫(xiě)測(cè)試類

    1. 測(cè)試類的命名規(guī)范:以Test開(kāi)頭,以業(yè)務(wù)類類名結(jié)尾,使用駝峰命名法
    2. 業(yè)務(wù)名稱是:UserService
    3. 測(cè)試這個(gè)業(yè)務(wù)類的測(cè)試類:TestUserService
  3. 在測(cè)試類中寫(xiě)測(cè)試方法

    1. 測(cè)試方法的命名規(guī)則:以test開(kāi)頭,以業(yè)務(wù)方法名結(jié)尾
      比如被測(cè)試業(yè)務(wù)方法名為:login,那么測(cè)試方法名就應(yīng)該叫:testLogin
  4. 測(cè)試方法注意事項(xiàng)

    1. 必須是public修飾的,沒(méi)有返回值,沒(méi)有參數(shù)
    2. 必須使注解@Test修飾

3.3 如何運(yùn)行測(cè)試方法

  1. 選中方法名 --> 右鍵 --> Run '測(cè)試方法名' 運(yùn)行選中的測(cè)試方法
  2. 選中測(cè)試類類名 --> 右鍵 --> Run '測(cè)試類類名' 運(yùn)行測(cè)試類中所有測(cè)試方法
  3. 選中模塊名 --> 右鍵 --> Run 'All Tests' 運(yùn)行模塊中的所有測(cè)試類的所有測(cè)試方法

3.4 如何查看測(cè)試結(jié)果

  1. 綠色:表示測(cè)試通過(guò)

  2. 紅色:表示測(cè)試失敗,有問(wèn)題

反射

1. 概述

1.1 反射

  1. 是Java的高級(jí)技術(shù),是Java獨(dú)有的技術(shù)。是Java技術(shù)顯著的特點(diǎn)。
  2. 反射是指對(duì)于任何一個(gè)類,在運(yùn)行的時(shí)候都可以直接得到這個(gè)類全部成分。
    1. 在運(yùn)行時(shí),可以直接得到這個(gè)類的構(gòu)造器對(duì)象。(Constructor)
    2. 在運(yùn)行時(shí),可以直接得到這個(gè)類的成員變量。(Field)
    3. 在運(yùn)行時(shí),可以直接得到這個(gè)類的成員方法。(Method)
  3. 反射的核心思想和關(guān)鍵就是得到:編譯以后的class文件對(duì)象。

1.2 小結(jié):

  1. 反射必須工作在運(yùn)行時(shí)。
  2. 反射的關(guān)鍵是得到編譯以后的Class文件對(duì)象
  3. 反射可以在運(yùn)行時(shí)得到一個(gè)類的全部成分進(jìn)行一些操作。

2. 獲取

2.1 類

  1. 反射技術(shù)的第一步永遠(yuǎn)是先得到Class類對(duì)象:有三種方式獲取

    1. 類名.class
    2. 通過(guò)類的對(duì)象.getClass()方法
    3. Class.forName("類的全限名")
    public static Class<?> forName(String className);
    
  2. Class類下的方法

    // 獲得類名字符串:類名
    String getSimpleName(); 
    
    // 獲得類全名:包名+類名
    String getName(); 
    
    // 創(chuàng)建Class對(duì)象關(guān)聯(lián)類的對(duì)象
    T newInstance() ; 
    

2.2 構(gòu)造器

  1. 反射中Class類型獲取構(gòu)造器提供了很多的API

    // 根據(jù)參數(shù)匹配獲取某個(gè)構(gòu)造器,只能拿public修飾的構(gòu)造器,幾乎不用!
    Constructor getConstructor(Class... parameterTypes);
    
    // 根據(jù)參數(shù)匹配獲取某個(gè)構(gòu)造器,只要申明就可以定位,不關(guān)心權(quán)限修飾符,建議使用!
    Constructor getDeclaredConstructor(Class... parameterTypes);
    
    // 獲取所有的構(gòu)造器,只能拿public修飾的構(gòu)造器。幾乎不用?。√趿?!
    3. Constructor[] getConstructors();
    
    // 獲取所有申明的構(gòu)造器,只要你寫(xiě)我就能拿到,無(wú)所謂權(quán)限。建議使用!!
    4. Constructor[] getDeclaredConstructors();
    
  2. 小結(jié):

    1. 獲取全部構(gòu)造器,建議用getDeclaredConstructors();
    2. 獲取某個(gè)構(gòu)造器,建議用getDeclaredConstructor(Class... parameterTypes)
    3. 他們都無(wú)所謂權(quán)限,只要申明了就可以去?。?!
    4. 反射是破環(huán)封裝性的!!

2.3 成員變量

  1. API

    // 根據(jù)成員變量名獲得對(duì)應(yīng)Field對(duì)象,只能獲得public修飾
    Field getField(String name);
    
    // 根據(jù)成員變量名獲得對(duì)應(yīng)Field對(duì)象,只要申明了就可以得到
    Field getDeclaredField(String name);
    
    // 獲得所有的成員變量對(duì)應(yīng)的Field對(duì)象,只能獲得public的
    Field[] getFields();
    
    // 獲得所有的成員變量對(duì)應(yīng)的Field對(duì)象,只要申明了就可以得到
    Field[] getDeclaredFields();
    
  1. Field的方法:給成員變量賦值和取值

    // 給對(duì)象注入某個(gè)成員變量數(shù)據(jù)
    void  set(Object obj, Object value);
    
    // 獲取對(duì)象的成員變量的值
    Object get(Object obj);
    
    // 暴力反射,設(shè)置為可以直接訪問(wèn)私有類型的屬性
    void setAccessible(true);
    
    // 獲取屬性的類型,返回Class對(duì)象
    Class getType(); 
    
    // 獲取屬性的名稱
    String getName(); 
    

2.4 方法

  1. 反射獲取類的Method方法對(duì)象

    // 根據(jù)方法名和參數(shù)類型獲得對(duì)應(yīng)的方法對(duì)象,只能獲得public的
    Method getMethod(String name,Class...args);
    
    // 根據(jù)方法名和參數(shù)類型獲得對(duì)應(yīng)的方法對(duì)象,包括private的
    Method getDeclaredMethod(String name,Class...args);
    
    // 獲得類中的所有成員方法對(duì)象,返回?cái)?shù)組,只能獲得public修飾的且包含父類的
    Method[] getMethods();
    
    // 獲得類中的所有成員方法對(duì)象,返回?cái)?shù)組,只獲得本類申明的方法
    Method[] getDeclaredMethods();
    
  2. Method的方法

    Object invoke(Object obj, Object... args)
    
  • 觸發(fā)的是哪個(gè)對(duì)象的方法執(zhí)行。
  • args:調(diào)用方法時(shí)傳遞的實(shí)例參數(shù)

3. 拓展:反射的作用

  1. 可以在運(yùn)行時(shí)得到一個(gè)類的全部成分然后操作。
  2. 可以破壞封裝性。
  3. 更重要的用途是適合:做Java高級(jí)框架,基本上主流框架都會(huì)基于反射設(shè)計(jì)一些通用功能。

注解

1. 注解的概念

1.1 注解

  1. 用在類上,方法上,成員變量方法,構(gòu)造器,...上對(duì)成分進(jìn)行編譯約束等操作的。
  2. 注解是JDK1.5的新特性。
  3. 注解相當(dāng)一種標(biāo)記,是類的組成部分,可以給類攜帶一些額外的信息。
  4. 注解是給編譯器或JVM看的,編譯器或JVM可以根據(jù)注解來(lái)完成對(duì)應(yīng)的功能。

1.2 注解作用

  1. 標(biāo)記。
  2. 方法重寫(xiě)約束 @Override
  3. 函數(shù)式接口約束。 @FunctionalInterface.
  4. 現(xiàn)今最牛逼的框架技術(shù)多半都是在使用注解和反射。

2. 自定義注解

2.1 自定義注解的格式

[修飾符] @interface 注解名{
// 注解屬性
}

2.2 小結(jié)

1.注解的定義是@interface
2.注解可以注釋類的成分,可以使用多個(gè)注解注釋同一個(gè)成分。

3. 注解的屬性

3.1 屬性的格式

  1. 格式1:數(shù)據(jù)類型 屬性名();
  2. 格式2:數(shù)據(jù)類型 屬性名() default 默認(rèn)值;

3.2 屬性適用的數(shù)據(jù)類型:

  1. 八種數(shù)據(jù)數(shù)據(jù)類型(int,short,long,double,byte
    ,char,boolean,float)
  2. String,Class,注解類型。
  3. 以上類型的數(shù)組形式都支持

3.3 小結(jié):

  1. 注解的屬性在使用的時(shí)候需要有值!默認(rèn)值可以不賦值!

3.4 注解的特殊屬性名稱:value

  1. value屬性,如果只有一個(gè)value屬性的情況下,使用value屬性的時(shí)候可以省略value名稱不寫(xiě)!!
  2. 但是如果有多個(gè)屬性,那么value是不能省略的。

4. 元注解

4.1 簡(jiǎn)介

  1. 元注解是sun公司提供的。
  2. 元注解是用在自定義注解上的注解。
  3. 元注解是用來(lái)注解自定義注解的。

4.2 元注解有兩個(gè):

  1. @Target:約束自定義注解只能在哪些地方使用,

    1. 作用:用來(lái)標(biāo)識(shí)注解使用的位置,如果沒(méi)有使用該注解標(biāo)識(shí),則自定義的注解可以使用在任意位置。

    2. 可使用的值定義在ElementType枚舉類中,常用值如下

      TYPE,類,接口
      FIELD, 成員變量
      METHOD, 成員方法
      PARAMETER, 方法參數(shù)
      CONSTRUCTOR, 構(gòu)造方法
      LOCAL_VARIABLE, 局部變量
      
    3. 但是默認(rèn)的注解可以在類,方法,構(gòu)造器,成員變量,... 使用。

  2. @Retention:申明注解的生命周期

    1. 作用:用來(lái)標(biāo)識(shí)注解的生命周期(有效范圍)
    2. 可使用的值定義在RetentionPolicy枚舉類中,常用值如下
    3. SOURCE:注解只作用在源碼階段,生成的字節(jié)碼文件中不存在
    4. CLASS:注解作用在源碼階段,字節(jié)碼文件階段,運(yùn)行階段不存在,默認(rèn)值
    5. RUNTIME:注解作用在源碼階段,字節(jié)碼文件階段,運(yùn)行階段(開(kāi)發(fā)常用)
    6. 申明注解的作用范圍:編譯時(shí),運(yùn)行時(shí)。

5. 注解解析

5.1 簡(jiǎn)介

  1. 我們會(huì)使用注解注釋一個(gè)類的成分,那么就設(shè)計(jì)到要解析出這些注解的數(shù)據(jù)。
  2. 開(kāi)發(fā)中經(jīng)常要知道一個(gè)類的成分上面到底有哪些注解,注解有哪些屬性數(shù)據(jù),這都需要進(jìn)行注解的解析。

5.2 與注解解析相關(guān)的接口

  1. Annotation: 注解類型,該類是所有注解的父類。注解都是一個(gè)Annotation的對(duì)象

  2. AnnotatedElement:該接口定義了與注解解析相關(guān)的方法

    /*
     所有的類成分Class, Method , Field , Constructor:都實(shí)現(xiàn)了AnnotatedElement接口
     他們都擁有解析注解的能力:
    */
    
    // 根據(jù)注解類型獲得對(duì)應(yīng)注解對(duì)象,會(huì)拿父類的注解
    T getAnnotation(Class<T> annotationClass);
    
    // 獲得當(dāng)前對(duì)象上使用的所有注解,返回注解數(shù)組
    Annotation[] getAnnotations()
    
    // 獲得當(dāng)前對(duì)象上使用的所有注解,返回注解數(shù)組,只包含本類的
    Annotation[] getDeclaredAnnotations()
    
    // 根據(jù)注解類型獲得對(duì)應(yīng)注解對(duì)象
    T getDeclaredAnnotation(Class<T> annotationClass)
    
    // 判斷當(dāng)前對(duì)象是否使用了指定的注解,如果使用了則返回true,否則false
    boolean isAnnotationPresent(Class<Annotation> annotationClass)
    

5.3 獲取注解數(shù)據(jù)的原理

  1. 注解在哪個(gè)成分上,我們就先拿哪個(gè)成分對(duì)象。
  2. 比如注解作用成員方法,則要獲得該成員方法對(duì)應(yīng)的Method對(duì)象,再來(lái)拿上面的注解
  3. 比如注解作用在類上,則要該類的Class對(duì)象,,再來(lái)拿上面的注解
  4. 比如注解作用在成員變量上,則要獲得該成員變量對(duì)應(yīng)的Field對(duì)象,再來(lái)拿上面的注解

6. 注解模擬Junit框架

  1. 定義若干個(gè)方法,只要加了MyTest注解,就可以被自動(dòng)觸發(fā)執(zhí)行。

  2. 分析:

    1. 定義一個(gè)自定義注解MyTest.
      • 只能注解方法。
    2. 定義若干個(gè)方法,只要有@MyTest注解的方法就能被觸發(fā)執(zhí)行!!沒(méi)有這個(gè)注解的方法不能執(zhí)行!!
  3. 小結(jié):
    反射+注解+泛型通常是做大型框架的核心技術(shù)!!可以做通用框架技術(shù)!

  4. 代碼實(shí)現(xiàn)

    注解模擬Junit框架.png

動(dòng)態(tài)代理

1. 問(wèn)題:

  1. 我們發(fā)現(xiàn)我們的業(yè)務(wù)功能方法,前后的邏輯代碼幾乎都是一樣,只是中間部分不一樣
  2. 如果能夠讓業(yè)務(wù)功能只處理自己的核心邏輯,其他的不用寫(xiě)就可以完成,這時(shí)候需要用動(dòng)態(tài)代理了?。?/li>

2. 核心:

  1. 做一個(gè)代理類,把業(yè)務(wù)對(duì)象的交個(gè)代理類,返回被代理對(duì)象。
  2. 以后調(diào)用被代理對(duì)象的功能,會(huì)先觸發(fā)代理類執(zhí)行。
  3. 把業(yè)務(wù)對(duì)象 -> 轉(zhuǎn)成被代理的業(yè)務(wù)對(duì)象

3. 代理類

newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
  • 參數(shù)一:給類的加載器,用于加載類。
  • 參數(shù)二:被代理對(duì)象所實(shí)現(xiàn)的全部接口,因?yàn)楸淮淼墓δ芏荚诮涌谥卸x。
  • 參數(shù)三:代理對(duì)象的處理方法:旅行社的功能。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 對(duì)象的創(chuàng)建與銷毀 Item 1: 使用static工廠方法,而不是構(gòu)造函數(shù)創(chuàng)建對(duì)象:僅僅是創(chuàng)建對(duì)象的方法,并非Fa...
    孫小磊閱讀 2,184評(píng)論 0 3
  • 整理來(lái)自互聯(lián)網(wǎng) 1,JDK:Java Development Kit,java的開(kāi)發(fā)和運(yùn)行環(huán)境,java的開(kāi)發(fā)工具...
    Ncompass閱讀 1,618評(píng)論 0 6
  • 一:java概述:1,JDK:Java Development Kit,java的開(kāi)發(fā)和運(yùn)行環(huán)境,java的開(kāi)發(fā)工...
    ZaneInTheSun閱讀 2,812評(píng)論 0 11
  • 今天和大家分享一下游武漢的攻略~ 前期的準(zhǔn)備工作很重要?。?!不要說(shuō)什么說(shuō)走就走的旅行,然后買(mǎi)了票就去了,你……大約...
    莫徯閱讀 688評(píng)論 3 4
  • 回憶經(jīng)年數(shù)蹉跎 燒起內(nèi)心青春夢(mèng) 看著電視不看人 依稀4587萌慧花 光腳走錯(cuò)房間 哦,自己還是哪個(gè)誰(shuí)嗎 滴落煙灰灼...
    敖包漢子閱讀 224評(píng)論 0 1

友情鏈接更多精彩內(nèi)容