Java---JUnita注解與類加載器詳解以及實(shí)例

      網(wǎng)友投稿 724 2022-05-29

      JUnit軟件測試技術(shù)(工具)

      在項(xiàng)目中建立專門用戶測試的包結(jié)構(gòu)。

      在Junit中,通過@Test注解,可以運(yùn)行一個方法。

      ★ Junit注解說明

      使用了@Test注解應(yīng)該滿足以下條件:

      1) 必須是無參數(shù)的非靜態(tài)方法。

      2) 添加@Test注解的類,必須擁有一個無參數(shù)的公開構(gòu)造

      ★ JUnit測試示例演示

      1、運(yùn)行完成后,可以在Junit的窗口上看到運(yùn)行所用的時間和結(jié)果信息。

      2、被測試程序的運(yùn)行結(jié)果出現(xiàn)在控制臺(Console)上。

      “項(xiàng)目”代碼:

      package cn.hncu.user.dao.dao; /** * @author 陳浩翔 * @version 1.0 2016-5-4 */ public interface UserDao { public abstract void fun1()throws Exception; public abstract void fun2(); public abstract void fun3(); }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      package cn.hncu.user.dao.impl; import cn.hncu.user.dao.dao.UserDao; /** * @author 陳浩翔 * @version 1.0 2016-5-4 */ public class UserDaoImpl implements UserDao{ @Override public void fun1() throws Exception { System.out.println("fun1...."); } @Override public void fun2() { System.out.println("fun2...."); } @Override public void fun3() { System.out.println("fun3...."); } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      package cn.hncu.user.dao.factory; import cn.hncu.user.dao.dao.UserDao; import cn.hncu.user.dao.impl.UserDaoImpl; /** * @author 陳浩翔 * @version 1.0 2016-5-4 */ public class UserDaoFactory { public static UserDao getUserDao(){ return new UserDaoImpl(); } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      隨便寫了幾個輸出。。。

      下面的是測試代碼:

      package cn.hncu.test; import org.junit.Test; import cn.hncu.user.dao.dao.UserDao; import cn.hncu.user.dao.factory.UserDaoFactory; import cn.hncu.user.dao.impl.UserDaoImpl; /** * @author 陳浩翔 * @version 1.0 2016-5-4 */ //使用@Test的條件2:該類必須具有一個無參構(gòu)造方法 public class TestUserDaoImpl { UserDao dao = UserDaoFactory.getUserDao(); /** * 測試fun1()方法 */ //使用@Test的條件1:測試方法必須是非靜態(tài)、無參 @Test public void testFun1(){ try { dao.fun1(); } catch (Exception e) { e.printStackTrace(); } } @Test public void testFun2() { dao.fun2(); } @Test public void testFun3() { dao.fun3(); } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      33

      34

      35

      36

      37

      38

      39

      40

      41

      42

      正確的演示結(jié)果:

      錯誤的演示結(jié)果:(沒有無參構(gòu)造方法)

      ★ JUnit中的其它注解

      @BeforeClass、@AfterClass、@Before、@After

      package cn.hncu.test; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import cn.hncu.user.dao.dao.UserDao; import cn.hncu.user.dao.factory.UserDaoFactory; import cn.hncu.user.dao.impl.UserDaoImpl; /** * @author 陳浩翔 * @version 1.0 2016-5-4 */ public class TestUserDaoImpl2 { UserDao dao = UserDaoFactory.getUserDao(); //注意要加static @BeforeClass public static void initFirst(){ System.out.println("finishEnd..."); } //在每次運(yùn)行@Test方法之前,都會先運(yùn)行這個@Before的方法 @Before public void init(){ System.out.println("init..."); } @Test public void testFun1(){ try { dao.fun1(); } catch (Exception e) { e.printStackTrace(); } } /*運(yùn)行結(jié)果 finishEnd... init... fun1.... finish... finishEnd... */ @Test public void testFun2() { dao.fun2(); } /*運(yùn)行結(jié)果 finishEnd... init... fun2.... finish... finishEnd... */ @Test public void testFun3() { dao.fun3(); } /*運(yùn)行結(jié)果 finishEnd... init... fun3.... finish... finishEnd... */ //在每次運(yùn)行@Test方法之后,都會最后運(yùn)行這個@After的方法 @After public void finish(){ System.out.println("finish..."); } //注意要加static @AfterClass public static void finishEnd(){ System.out.println("finishEnd..."); } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      33

      34

      35

      36

      37

      38

      39

      40

      41

      42

      43

      44

      45

      46

      47

      48

      49

      50

      51

      52

      53

      54

      55

      56

      57

      58

      59

      60

      61

      62

      63

      64

      65

      66

      67

      68

      69

      70

      71

      72

      73

      74

      75

      76

      77

      78

      79

      80

      81

      82

      83

      84

      85

      86

      87

      注解 ( Annotation )

      ★ 元數(shù)據(jù)

      所謂元數(shù)據(jù)就是數(shù)據(jù)的數(shù)據(jù)。也就是說,元數(shù)據(jù)是描述數(shù)據(jù)的。就象數(shù)據(jù)表中的字段一樣,每個字段描述了這個字段下的數(shù)據(jù)的含義。 元數(shù)據(jù)可以用于創(chuàng)建文檔,跟蹤代碼中的依賴性,甚至執(zhí)行基本編譯時檢查。許多元數(shù)據(jù)工具,如XDoclet,將這些功能添加到核心Java語言中,暫時成為Java編程功能的一部分。 一般來說,元數(shù)據(jù)的好處分為三類:文檔編制、編譯器檢查和代碼分析。代碼級文檔最常被引用。元數(shù)據(jù)提供了一種有用的方法來指明方法是否取決于其他方法,它們是否完整,特定類是否必須引用其他類,等等。

      1

      2

      3

      ★ 什么是注解

      Java中的注解就是Java源代碼的元數(shù)據(jù),也就是說注解是用來描述Java源代碼的。 基本語法就是:@后面跟注解的名稱。

      像前面演示的那幾個都是注解。

      ★ Java中預(yù)定義注解

      ①Override:標(biāo)識某一個方法是否正確覆蓋了它的父類的方法。

      (如果用了這個注解,但是父類中沒有這個方法,就會報錯)

      ②Deprecated:表示已經(jīng)不建議使用這個類成員了。 它是一個標(biāo)記注解。

      (用了這個注解的,表示在下一個升級版本中,可能不會有這個方法了,但是會有類似功能的方法代替,會在注釋中提出)

      ③SuppressWarnings:用來抑制警告信息。

      (例如:壓泛型的警告)

      (這個是可以傳參進(jìn)去的,可以實(shí)現(xiàn)不同的功能)

      自定義注解1

      自定義注解的語法很簡單,跟定義接口類似,只是在名稱前面加上@符號。

      ★ 最簡單的自定義注解

      public @interface MyAnno { }

      1

      2

      ★ 使用這個注解

      和使用其他注解是一樣的

      @MyAnno public class UserModel{ }

      1

      2

      3

      ★ 為注解添加成員

      //定義 public @interface MyAnno { public String schoolName(); }

      1

      2

      3

      4

      //使用 @MyAnno(schoolName="湖南城市學(xué)院") public class UserModel{ }

      1

      2

      3

      4

      5

      ★ 設(shè)置默認(rèn)值

      //定義 public @interface MyAnno { public String schoolName() default "湖南城市學(xué)院"; }

      1

      2

      3

      4

      //使用1 @MyAnno public class UserModel{ }

      1

      2

      3

      4

      //使用2 @MyAnno(schoolName="城院Java高手訓(xùn)練營") public class UserModel{ }

      1

      2

      3

      4

      對注解的注解

      package cn.hncu.anno; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD,ElementType.TYPE}) public @interface MyAnno { }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      ☆指定目標(biāo) Target

      在了解如何使用Target 之前,需要認(rèn)識另一個類,該類被稱為ElementType (通過API詳細(xì)學(xué)習(xí)) ,它實(shí)際上是一個枚舉。這個枚舉定義了注釋類型可應(yīng)用的不同程序元素。

      //如果都不寫,就是隨便在哪里都可以用

      @Target({ ElementType.TYPE, ElementType.METHOD})

      1

      //這個注解可以在哪里用,TYPE-可以在類上面用,METHOD-可以在方法上用

      ☆設(shè)置保持性 Retention

      RetentionPolicy (通過API詳細(xì)學(xué)習(xí))枚舉類中定義了3種注解保持性,分別決定了Java 編譯器以何種方式處理注解。

      @Retention(RetentionPolicy.RUNTIME)

      1

      //運(yùn)行時VM虛擬機(jī)也能識別這個注解,這個注解一直存在

      @Retention(RetentionPolicy.SOURCE)

      1

      //class文件中有這個注解,但是VM虛擬機(jī)運(yùn)行時,忽略這個注解了。

      (這是默認(rèn)的)

      ☆添加公共文檔 Documented

      在默認(rèn)的情況下在使用javadoc自動生成文檔時,注解將被忽略掉。如果想在文檔中也包含注解,必須使用Documented為文檔注解。

      ☆設(shè)置繼承 Inherited

      在默認(rèn)的情況下,父類的注解并不會被子類繼承。如果要繼承,就必須加上Inherited注解。

      如何讀取注解

      要讀取注解的內(nèi)容,就需要使用反射的技術(shù)。

      注意:要想使用反射得到注釋信息,必須用@Retention(RetentionPolicy.RUNTIME)進(jìn)行注解。

      /** * 分別讀取類上的@MyAnno注解 和 方法上的@MyAnno注解 */ @Test public void readAnno(){ //※※注意:MyAnno注解定義時,必須指定它的保持性為 RUNTIME,否則下面是讀取不出注解的 //以下方式是讀取“聲明在類上的”MyAnno注解 Class c = UserModel.class; //boolean boo = c.isAnnotationPresent(cn.hncu.anno.MyAnno.class); //boolean boo = c.isAnnotationPresent(MyAnno.class); boolean boo = (c.getAnnotation(MyAnno.class)!=null); System.out.println(boo); //以下方式是讀取“聲明在方法上的”MyAnno注解 Method ms[] = c.getDeclaredMethods(); for(Method m:ms){ if(m.isAnnotationPresent(MyAnno.class)){ System.out.println(m.getName()+"方法上有@MyAnno注解"); } } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      結(jié)果:

      true getAge方法上有@MyAnno注解 getId方法上有@MyAnno注解

      1

      2

      3

      4

      類加載器

      Java虛擬機(jī)中可以安裝多個類加載器,系統(tǒng)默認(rèn)三個主要類加載器,每個類負(fù)責(zé)加載特定位置的類:

      BootStrap, ExtClassLoader, AppClassLoader

      @Test public void systemLoaderDemo(){ ClassLoader loader = Person.class.getClassLoader(); System.out.println(loader);//AppClassLoader loader = loader.getParent(); System.out.println(loader);//ExtClassLoader loader = loader.getParent(); System.out.println(loader);//null }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      因?yàn)锽ootStrap是最底層,用C寫的,我們不能訪問到,我們沒有權(quán)限,所以輸出就是null了。

      類加載器也是Java類,因?yàn)槠渌莏ava類的類加載器本身也要被類加載器加載,顯然必須有第一個類加載器不是java類,這正是BootStrap。

      Java虛擬機(jī)中的所有類裝載器采用具有父子關(guān)系的樹形結(jié)構(gòu)進(jìn)行組織,在實(shí)例化每個類裝載器對象時,需要為其指定一個父級類裝載器對象或者默認(rèn)采用系統(tǒng)類裝載器為其父級類加載。

      ☆類加載器的委托機(jī)制

      通過API認(rèn)識ClassLoader類

      當(dāng)Java虛擬機(jī)要加載一個類時,到底派出哪個類加載器去加載呢?

      首先當(dāng)前線程的類加載器去加載線程中的第一個類。如果類A中引用了類B,Java虛擬機(jī)將使用加載類A的類裝載器來加載類B。

      還可以直接調(diào)用ClassLoader.loadClass()方法來指定某個類加載器去加載某個類。

      每個類加載器加載類時,又先委托給其上級類加載器。當(dāng)所有祖宗類加載器沒有加載到類,回到發(fā)起者類加載器,還加載不了,則拋ClassNotFoundException,不是再去找發(fā)起者類加載器的兒子,因?yàn)闆]有g(shù)etChild方法,即使有,那有多個兒子,找哪一個呢?

      對著類加載器的層次結(jié)構(gòu)圖和委托加載原理,解釋先前將ClassLoaderTest輸出成jre/lib/ext目錄下的aa.jar包中后,運(yùn)行結(jié)果為ExtClassLoader的原因。

      演示不是classpath下的類,系統(tǒng)類加載器是無法加載的

      Person類:

      package cn.hncu; /** * * @author 陳浩翔 * * @version 1.0 2016-5-4 */ public class Person { private String name; private int age; public Person() { } public Person(String name, int age) { this.name = name; this.age = age; } 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 "Person [name=" + name + ", age=" + age + "]"; } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      27

      28

      29

      30

      31

      32

      33

      34

      35

      36

      37

      38

      39

      40

      41

      @Test public void loaderLocalClassDemo() throws ReflectiveOperationException{ Class c = Class.forName("cn.hncu.Person"); System.out.println(c); Object obj = c.newInstance(); System.out.println(obj); }

      1

      2

      3

      4

      5

      6

      7

      8

      運(yùn)行結(jié)果:

      class cn.hncu.Person Person [name=null, age=0]

      1

      2

      3

      再看:

      我把Person.class移到d:\cn\hncu

      //不是classpath下的類,系統(tǒng)類加載器是無法加載的---如果要加載,得自己寫類加載器 @Test public void loaderRemoteClassDemo() throws ReflectiveOperationException{ Class c = Class.forName("d:\cn\hncu\Person.class"); System.out.println(c); Object obj = c.newInstance(); System.out.println(obj); }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      結(jié)果:

      掛了,不能運(yùn)行了。

      因?yàn)闆]有配置classpath。

      對著類加載器的層次結(jié)構(gòu)圖和委托加載原理,解釋先前將ClassLoaderTest輸出成jre/lib/ext目錄下的aa.jar包中后,運(yùn)行結(jié)果為ExtClassLoader

      必須是壓.class文件,不要壓縮.java文件。!!!!

      package cn.hncu; /** * * @author 陳浩翔 * * @version 1.0 2016-5-4 */ public class LoaderDemo { public static void main(String[] args) { LoaderDemo a = new LoaderDemo(); System.out.println(a); } @Override public String toString() { return "隨便演示。。。chx"; } }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      先按照這個命令打包這個.java

      package cn.hncu; /** * * @author 陳浩翔 * * @version 1.0 2016-5-4 */ public class LoaderDemo { public static void main(String[] args) { LoaderDemo a = new LoaderDemo(); System.out.println(a); } @Override public String toString() { return "湖南城院。。。隨便演示...chx"; } //改了沒用。已經(jīng)不會運(yùn)行這里的代碼了。 }

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      大家看輸出結(jié)果:

      對著類加載器的層次結(jié)構(gòu)圖和委托加載原理,解釋先前將ClassLoaderTest輸出成jre/lib/ext目錄下的aa.jar包中后,運(yùn)行結(jié)果還是為ExtClassLoader。

      Java---JUnita、注解與類加載器詳解以及實(shí)例

      也就是那三層從上到下,如果上面已經(jīng)有那個類了,就不會運(yùn)行下面的那個類:

      BootStrap—>ExtClassLoader—>AppClassLoader(System classLoader)

      大家再看看這個圖,是不是感覺容易理解一些了:

      Java

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:python文檔:開始進(jìn)入編程(在前面的基礎(chǔ)上)
      下一篇:《企業(yè)級大數(shù)據(jù)平臺構(gòu)建:架構(gòu)與實(shí)現(xiàn)》——2.4.8 使用場景
      相關(guān)文章
      国产亚洲人成网站在线观看不卡| 亚洲AV无码一区二区三区在线观看 | 亚洲人成影院77777| 亚洲αv在线精品糸列| 国产亚洲av人片在线观看| 亚洲成年人啊啊aa在线观看| 青青青国产色视频在线观看国产亚洲欧洲国产综合| 亚洲已满18点击进入在线观看| 亚洲av无码电影网| 亚洲伊人久久大香线蕉结合| 亚洲日本久久一区二区va| 国产成人精品日本亚洲网址| 亚洲黄页网在线观看| 亚洲 欧洲 视频 伦小说| 久久亚洲精品国产精品婷婷| 亚洲人成人伊人成综合网无码| 亚洲中文字幕乱码熟女在线| 亚洲欧美日韩中文字幕在线一区| 亚洲人AV在线无码影院观看| 亚洲精品国产av成拍色拍| 五月天婷亚洲天综合网精品偷| 亚洲Av无码乱码在线观看性色| 国产成人亚洲综合无码| 亚洲一区二区三区无码中文字幕| 精品久久香蕉国产线看观看亚洲| 亚洲国产精品无码一线岛国| 亚洲AV乱码一区二区三区林ゆな| 久久久久亚洲AV片无码下载蜜桃| 亚洲精品偷拍无码不卡av| 亚洲视频一区二区三区四区| 亚洲国产成人久久精品软件| 亚洲精品老司机在线观看| 亚洲一区二区三区无码中文字幕| 亚洲av成人无码久久精品| 久久久久亚洲Av无码专| avtt天堂网手机版亚洲| 大桥未久亚洲无av码在线| 国产精品亚洲精品日韩已方| 亚洲国产另类久久久精品 | 亚洲狠狠色丁香婷婷综合| 另类小说亚洲色图|