知識模塊 一.Junit單元測試 二.反射 三.枚舉 一.Junit單元測試 a.概述 Junit是一種Java寫的單元測試框架,專門用來測試Java程序,它可以取代main方法 b.Junit環(huán)境搭建 由于Junit使用的類不屬于我們JDK的類庫,需要引入第三方j(luò)ar包才能使用 c.Junit使用 /* Junit單元測試使用 我們測試方法只需要在方法上添加一個注解 @Test 1.我們在不同的方法上加上@Test,每個方法都可以獨立運行 2.如果在類上運行,那么會測試該類的所有方法,如果有一個方法測試失敗,那么該類就測試失敗 各個方法 獨立測試,相互不影響 */
import org.junit.Test;
/*
Junit單元測試使用
我們測試方法只需要在方法上添加一個注解 @Test
1.我們在不同的方法上加上@Test,每個方法都可以獨立運行
2.如果在類上運行,那么會測試該類的所有方法,如果有一個方法測試失敗,那么該類就測試失敗
各個方法 獨立測試,相互不影響
*/
public class JunitDemo01 {
/* public static void main(String[] args) {
int[] arr = {3, 5, 7,};
for (int i : arr) {
System.out.println(i);
}*/
@Test
public void method01() {
int[] arr = {3, 5, 7,};
for (int i : arr) {
System.out.println(i);
}
}
@Test
public void method02() {
System.out.println(1 / 0);
}
@Test
public void method03() {
int[] arr = {3, 7, 5,};
int sum=0;
for (int i : arr) {
sum += i;
}
System.out.println(sum);
}
}
d.Junit注意事項 /* Junit注意事項: @Test 只能用在基于一下模板定義的方法 public void 方法名(){ } 1.權(quán)限修飾符必須是public 2.返回值類型必須為void 3.形參列表必須為空 4.該方法不能是靜態(tài)方法 */
import org.junit.Test;
/*
Junit注意事項:
@Test 只能用在基于一下模板定義的方法
public void 方法名(){
}
1.權(quán)限修飾符必須是public
2.返回值類型必須為void
3.形參列表必須為空
4.該方法不能是靜態(tài)方法
*/
public class JunitDemo02 {
@Test
private void method01() {
System.out.println("私有方法");
}
@Test
public int method02() {
return 3;
}
@Test
public void method03(int i) {
System.out.println(i);
}
@Test
private static void method04() {
System.out.println("私有方法");
}
}
/* 調(diào)用非public void method(){}的方法 解決方案: 先定義一個可以使用2Test注解方法,然后去調(diào)用不能使用@Test注解方法來達(dá)到測試目的 */
import org.junit.Test;
/*
調(diào)用非public void method(){}的方法
解決方案:
先定義一個可以使用2Test注解方法,然后去調(diào)用不能使用@Test注解方法來達(dá)到測試目的
*/
public class JunitDemo03 {
@Test
public void testMethod01() {
//System.out.println("abc");
method01();
System.out.println(method02());
}
@Test
public void testMethod02() {
method03(15);
}
@Test
public void testMethod03() {
JunitDemo03.method04();
method04();
}
private void method01() {
System.out.println("私有方法");
}
public int method02() {
return 3;
}
public void method03(int i) {
System.out.println(i);
}
private static void method04() {
System.out.println("靜態(tài)方法");
}
}
二.反射 a.字節(jié)碼對象 當(dāng)JVM用到一個類的時候,會把這個類加載到內(nèi)存中,首先在方法區(qū)存放類的定義信息 還要再堆內(nèi)存中創(chuàng)建一個字節(jié)碼對象和類文件(字節(jié)碼文件)一一對應(yīng) b.class類 參見圖解 c.反射(reflect)概述 反射其實就是解剖一個類,獲取類中的各項信息(構(gòu)造方法,成員變量,成員方法) 類比: 法醫(yī)解剖人的尸體,人體內(nèi)有很多器官(心肝脾肺腎),法醫(yī)獲取這些器官 程序員解剖一個類,類中有構(gòu)造方法信息,成員變量信息,成員方法信息,程序員獲取這些信息 d.獲取字節(jié)碼對象三種方式 /* 反射第一步獲取字節(jié)碼對象,因為只有獲取到字節(jié)碼對象,才能進(jìn)一步獲取類中的信息 三種方式: 1.類名.class 代表一個字節(jié)碼對象 2.通過Class類的方法,所以字節(jié)碼對象都是Class類的實例 static Class<?> forName(String className) 返回與帶有給定字符串名的類或接口相關(guān)聯(lián)的 Class 對象。 3.通過Object類中的getClass()方法獲取該類的字節(jié)碼對象 Class<?> getClass() 返回此 Object 的運行時類。 無論采用哪種方式獲取該類的字節(jié)碼對象,都是獲取了同一個字節(jié)碼對象 */
/*
解剖Person類
*/
public class Person {
public String name;
int age=13;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
private Person(String name) {
this.name = name;
}
public void sleep() {
System.out.println("只有睡得好,精神才能好");
}
public String eat(String food) {
System.out.println("人吃" + food);
return food;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
import org.junit.Test;
/*
反射第一步獲取字節(jié)碼對象,因為只有獲取到字節(jié)碼對象,才能進(jìn)一步獲取類中的信息
三種方式:
1.類名.class 代表一個字節(jié)碼對象
2.通過Class類的方法,所以字節(jié)碼對象都是Class類的實例
static Class<?> forName(String className)
返回與帶有給定字符串名的類或接口相關(guān)聯(lián)的 Class 對象。
3.通過Object類中的getClass()方法獲取該類的字節(jié)碼對象
Class<?> getClass()
返回此 Object 的運行時類。
無論采用哪種方式獲取該類的字節(jié)碼對象,都是獲取了同一個字節(jié)碼對象
*/
public class ReflectDemo01 {
@Test
public void testMethod01() {
System.out.println(Person.class);//class reflect01.Person
}
@Test
public void testMethod02() throws ClassNotFoundException {
/*Class p = Class.forName("Perosn");
System.out.println(p);*/
Class p = Class.forName("reflect01.Person");
System.out.println(p);//class reflect01.Person
}
@Test
public void testMethod03() {
Person p = new Person();
System.out.println(p.getClass());//class reflect01.Person
}
@Test
public void testMethod() throws ClassNotFoundException {
Class p1 = Person.class;
Class p2 = Class.forName("reflect01.Person");
Class p3 = new Person().getClass();
System.out.println(p1 == p2);//true
System.out.println(p2 == p3);//true
System.out.println(p1 == p3);//true
}
}
e.反射構(gòu)造方法 /* 反射(解剖出)構(gòu)造方法 Class<T>:T代表字節(jié)碼對象所表示得類 基本的 Java 類型(boolean、byte、char、short、int、long、float 和 double)和關(guān)鍵字 void 也表示為 Class 對象。 只需要將基本類型后面加上.class就表示Class的實例 Class類中的成員方法 Constructor<T> getConstructor(Class<?>... parameterTypes) 返回一個 Constructor 對象,它反映此 Class 對象所表示的類的指定公有(public)構(gòu)造方法。 <T>:T代表字節(jié)碼對象所表示得類 Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 獲取類中聲明的任意一個構(gòu)造方法 T newInstance() 只能利用該類的空參構(gòu)造對象,不能利用有參創(chuàng)建對象 Constructor類中的方法 String getName() 以字符串形式返回此構(gòu)造方法的名稱。 T newInstance(Object... initargs) 使用此 Constructor 對象表示的構(gòu)造方法來創(chuàng)建該構(gòu)造方法的聲明類的新實例,并用指定的初始化參數(shù)初始化該實例。 */
import org.junit.Test;
import reflect01.Person;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/*
反射(解剖出)構(gòu)造方法
Class<T>:T代表字節(jié)碼對象所表示得類
基本的 Java 類型(boolean、byte、char、short、int、long、float 和 double)和關(guān)鍵字 void 也表示為 Class 對象。
只需要將基本類型后面加上.class就表示Class的實例
Class類中的成員方法
Constructor<T> getConstructor(Class<?>... parameterTypes)
返回一個 Constructor 對象,它反映此 Class 對象所表示的類的指定公有(public)構(gòu)造方法。
<T>:T代表字節(jié)碼對象所表示得類
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
獲取類中聲明的任意一個構(gòu)造方法
T newInstance()
只能利用該類的空參構(gòu)造對象,不能利用有參創(chuàng)建對象
Constructor類中的方法
String getName()
以字符串形式返回此構(gòu)造方法的名稱。
T newInstance(Object... initargs)
使用此 Constructor 對象表示的構(gòu)造方法來創(chuàng)建該構(gòu)造方法的聲明類的新實例,并用指定的初始化參數(shù)初始化該實例。
*/
public class ReflectDemo01 {
@Test
public void testMethod01() throws Exception{
//1.獲取字節(jié)碼對象
Class<Person> pCLs = Person.class;
//2.獲取構(gòu)造方法
Constructor<Person> cons = pCLs.getConstructor();//由于獲取的是空參構(gòu)造,所以不需要傳遞任何參數(shù),因此使用getConstructor()方法也不用傳遞參數(shù)
//3.獲取構(gòu)造方法的信息
System.out.println(cons.getName());//獲取構(gòu)造方法的名稱 reflect01.Person
//4.利用構(gòu)造方法創(chuàng)建對象
Person p = cons.newInstance();//利用空參構(gòu)造創(chuàng)建對象
//類比:Person p = new Perosn();
System.out.println(p);//reflect01.Person@f5f2bb7
}
@Test
public void testMethod02() throws Exception{
//1.獲取字節(jié)碼對象
Class<Person> pCLs = Person.class;
//2.直接利用Class類的newInstance()方法創(chuàng)建該類實例
Person p = pCLs.newInstance();
System.out.println(p); //reflect01.Person@f5f2bb7
}
@Test
public void testMethod() throws Exception{
//1.獲取字節(jié)碼對象并獲取有參構(gòu)造
Constructor<Person> cons = Person.class.getConstructor(String.class, int.class);//獲取指定形參為String,int的方法
//2.利用這個有參構(gòu)造創(chuàng)建對象
Person p = cons.newInstance("老王", 30);//類比:Perosn p = new Person("老王",30);
System.out.println(p);
}
/**
* 暴力反射:獲取類中的一些私有屬性
* @throws Exception
*/
@Test
public void testMethod04() throws Exception {
//1.獲取字節(jié)碼對象
Class<Person> pCLs = Person.class;
//2.獲取構(gòu)造方法
//Constructor<Person> cons = pCLs.getConstructor(String.class);
Constructor<Person> cons = pCLs.getDeclaredConstructor(String.class);
//2.5由于是將要利用私有構(gòu)造方法創(chuàng)建對象,在類外無法調(diào)用私有構(gòu)造方法,但是我們可以讓java取消權(quán)限檢查
cons.setAccessible(true);
//3.構(gòu)造方法創(chuàng)建對象
Person p = cons.newInstance("老李");//類似:Person p = new Person("老李");
System.out.println(p);
}
}
f.反射成員變量(字段) /** * 反射(解剖出)字段 * Class類中的成員方法 * Field getField(String name) * 返回一個 Field 對象,它反映此 Class 對象所表示的類或接口的指定公共public成員字段。 * * Field getDeclaredField(String name) * 返回一個 Field 對象,該對象反映此 Class 對象所表示的類或接口的指定已聲明字段。 * * Field類中的成員方法 * Object get(Object obj) * 返回指定對象上此 Field 表示的字段的值。 */
import org.junit.Test;
import reflect01.Person;
import java.lang.reflect.Field;
/*
* 反射(解剖出)字段
* Class類中的成員方法
* Field getField(String name)
* 返回一個 Field 對象,它反映此 Class 對象所表示的類或接口的指定公共public成員字段。
*
* Field getDeclaredField(String name)
* 返回一個 Field 對象,該對象反映此 Class 對象所表示的類或接口的指定已聲明字段。
*
* Field類中的成員方法
* Object get(Object obj)
* 返回指定對象上此 Field 表示的字段的值。
*/
public class ReflectDemo02 {
@Test
public void testMethod01() throws Exception {
//1.獲取Person類的字節(jié)碼對象
Class<Person> pCLs = (Class<Person>) Class.forName("reflect01.Person");
//2.獲取字段信息
Field f = pCLs.getField("name");
//System.out.println(f); //public java.lang.String reflect01.Person.name
//3.獲取該字段的值
Person p = pCLs.newInstance(); //相當(dāng)于Person p = new Person();
System.out.println(f.get(p)); //由于成員對象隨著對象的存在二存在,所以必須指定獲取哪個對象的成員變量的值
}
@Test
public void testMethod02() throws Exception {
//1.獲取Person類的字節(jié)碼對象
Class<Person> pCLs = (Class<Person>) Class.forName("reflect01.Person");
//2.利用getDeclarField方法獲取非public修飾的字段
Field f = pCLs.getDeclaredField("age");
//2.5通過setAccessiable設(shè)置Java的訪問權(quán)限檢查
f.setAccessible(true);
//3.獲取當(dāng)前field字段的值
Person p = pCLs.newInstance();//相當(dāng)于Person p = new Person();
System.out.println(f.get(p));//13
//4.設(shè)置當(dāng)前field字段的值
f.set(p, 28);
//5.獲取當(dāng)前field字段的值
System.out.println(f.get(p));//28
}
}
g.反射成員方法 /* * 反射(解剖出)成員方法信息 * * Class類中的成員方法 * Method getMethod(String name, Class<?>... parameterTypes) * 返回一個 Method 對象,它反映此 Class 對象所表示的類或接口的指定公共成員方法。 * *Method類的方法: * Object invoke(Object obj, Object... args) * 形參: * Object obj:代表該類的一個對象 * orgs:代表傳遞給方法的實參 * 返回值: * 代表調(diào)用的方法的返回值 * 如果該方法沒有返回值,invoke()返回null */
import org.junit.Test;
import reflect01.Person;
import java.lang.reflect.Method;
/*
* 反射(解剖出)成員方法信息
*
* Class類中的成員方法
* Method getMethod(String name, Class<?>... parameterTypes)
* 返回一個 Method 對象,它反映此 Class 對象所表示的類或接口的指定公共成員方法。
*
*Method類的方法:
* Object invoke(Object obj, Object... args)
* 形參:
* Object obj:代表該類的一個對象
* orgs:代表傳遞給方法的實參
* 返回值:
* 代表調(diào)用的方法的返回值
* 如果該方法沒有返回值,invoke()返回null
*/
public class ReflectDemo03 {
@Test
public void testMethod01() throws Exception {
//1.獲取字節(jié)碼對象
Class<Person> pCLs = (Class<Person>) Class.forName("reflect01.Person");
//2.獲取指定的成員方法
Method sleepMethod = pCLs.getMethod("sleep");
//3.通過invoke來調(diào)用該方法
Person p = pCLs.newInstance();
System.out.println(sleepMethod.invoke(p));//類似: Person p = new Person();
// p.sleep();
}
@Test
public void testMethod02() throws Exception {
//1.獲取字節(jié)碼對象
Class<Person> pCLs = (Class<Person>) Class.forName("reflect01.Person");
//2.獲取eat方法
Method eatMethod = pCLs.getMethod("eat", String.class);
//3.調(diào)用eat方法
Person p = pCLs.newInstance();
Object returnVal = eatMethod.invoke(p, "榴蓮");//相當(dāng)于:Person p = new Person();
//String food = p.eat("蛋糕");
//Ststem.out.println(food);
System.out.println(returnVal);
}
}
三.枚舉 a.枚舉概述 一一列舉 如果某些變量的取值是固定幾個值中其中一個,我們就考慮定義枚舉 星期(一~日) 月份(1~12) 性別(男/女) b.模擬java中的枚舉 /* *一周(星期一~星期日) * 1.我們?yōu)橐恢苊刻於x一個Week對象,每個Week對象都代表改天 * */ public class Week { /* *私有化構(gòu)造方法目的:只能使用Week類中的這七個對象 * 而不能在類外在創(chuàng)建該類對象 */ private Week() { } private String weekName;//代表星期的名稱 private Week(String weekName) { this.weekName=weekName; } /* *public: 保證權(quán)限足夠大,在類外以及不同的包下都能訪問 *static: 不需要再類外創(chuàng)建對象,可以用過類名直接調(diào)用 * final: final修飾變量,該變量只能被賦值一次,該變量就成為了常量 * 常量的命名規(guī)范:變量名純大寫 XXX_XXX_XXX */ /* public static final Week MONDAY = new Week(); public static final Week TUESDAY = new Week(); public static final Week WEDNESDAY = new Week(); public static final Week THURSDAY = new Week(); public static final Week FRIDAY = new Week(); public static final Week SATURDAY = new Week(); public static final Week SUNDAY = new Week();*/ public static final Week MONDAY = new Week("星期一"); public static final Week TUESDAY = new Week("星期二"); public static final Week WEDNESDAY = new Week("星期三"); public static final Week THURSDAY = new Week("星期四"); public static final Week FRIDAY = new Week("星期五"); public static final Week SATURDAY = new Week("星期六"); public static final Week SUNDAY = new Week("星期日"); @Override public String toString() { return weekName; } }
import org.junit.Test;
public class WeekDemo {
@Test
public void testMethod01() {
//Week week = new Week();
//Week.monday=null;
System.out.println(Week.MONDAY);
System.out.println(Week.FRIDAY);
}
}
/*
*一周(星期一~星期日)
* 1.我們?yōu)橐恢苊刻於x一個Week對象,每個Week對象都代表改天
*
*/
public class Week {
/*
*私有化構(gòu)造方法目的:只能使用Week類中的這七個對象
* 而不能在類外在創(chuàng)建該類對象
*/
private Week() {
}
private String weekName;//代表星期的名稱
private Week(String weekName) {
this.weekName=weekName;
}
/*
*public: 保證權(quán)限足夠大,在類外以及不同的包下都能訪問
*static: 不需要再類外創(chuàng)建對象,可以用過類名直接調(diào)用
* final: final修飾變量,該變量只能被賦值一次,該變量就成為了常量
* 常量的命名規(guī)范:變量名純大寫 XXX_XXX_XXX
*/
/* public static final Week MONDAY = new Week();
public static final Week TUESDAY = new Week();
public static final Week WEDNESDAY = new Week();
public static final Week THURSDAY = new Week();
public static final Week FRIDAY = new Week();
public static final Week SATURDAY = new Week();
public static final Week SUNDAY = new Week();*/
public static final Week MONDAY = new Week("星期一");
public static final Week TUESDAY = new Week("星期二");
public static final Week WEDNESDAY = new Week("星期三");
public static final Week THURSDAY = new Week("星期四");
public static final Week FRIDAY = new Week("星期五");
public static final Week SATURDAY = new Week("星期六");
public static final Week SUNDAY = new Week("星期日");
@Override
public String toString() {
return weekName;
}
}
c.利用enum創(chuàng)建枚舉 /* * Java中利用enum關(guān)鍵字定義枚舉 * 格式: * 權(quán)限修飾符 enum 枚舉名稱{ * 枚舉變量1,枚舉變量2,枚舉變量3....; * } * * JAVA中利用enum定義的枚舉和我們自己模擬的枚舉原理相同 */ public enum Week { MONDAY("星期一"),THESDAY("星期二"),WEDNESDAY("星期三"),THURSDAY("星期四"), FRIDAY("星期五"),SATURDAY("星期六"),SUNDAY("星期日"); private String weekName; private Week(String weekName) { this.weekName=weekName; } private Week() { } @Override public String toString() { return weekName; } }
/*
* Java中利用enum關(guān)鍵字定義枚舉
* 格式:
* 權(quán)限修飾符 enum 枚舉名稱{
* 枚舉變量1,枚舉變量2,枚舉變量3....;
* }
*
* JAVA中利用enum定義的枚舉和我們自己模擬的枚舉原理相同
*/
public enum Week {
MONDAY,THESDAY,WEDNESDAY,THURSDAY,
FRIDAY,SATURDAY,SUNDAY
}
import org.junit.Test;
public class WeekDemo {
@Test
public void testMethod() {
//Week week = new Week();
System.out.println(Week.MONDAY);
System.out.println(Week.FRIDAY);
System.out.println(Week.MONDAY.getClass());//class enum03.Week
}
}
d.枚舉中常用的方法 /* *枚舉中的常用方法 * Java中所有用enum定義的枚舉默認(rèn)會繼承一個類:java.lang.Enum * * Class類中的方法 * Class<? super T> getSuperclass() * 獲取該字節(jié)碼對象的父類字節(jié)碼對象 * * Method[] getMethods() * 獲取該字節(jié)碼對象中所有public修飾的成員方法 * * 枚舉中的常用方法: * public static Week[] values() * 獲取所有的枚舉常量,并把所有的枚舉常量封裝到一個數(shù)組中返回 * public static Week.valueOf(String str) * public final String name() 返回此枚舉常量的名稱,在其枚舉聲明中對其進(jìn)行聲明。 * */
/*
* Java中利用enum關(guān)鍵字定義枚舉
* 格式:
* 權(quán)限修飾符 enum 枚舉名稱{
* 枚舉變量1,枚舉變量2,枚舉變量3....;
* }
*
* JAVA中利用enum定義的枚舉和我們自己模擬的枚舉原理相同
*/
public enum Week {
MONDAY,THESDAY,WEDNESDAY,THURSDAY,
FRIDAY,SATURDAY,SUNDAY
}
import org.junit.Test;
import java.lang.reflect.Method;
/*
*枚舉中的常用方法
* Java中所有用enum定義的枚舉默認(rèn)會繼承一個類:java.lang.Enum
*
* Class類中的方法
* Class<? super T> getSuperclass()
* 獲取該字節(jié)碼對象的父類字節(jié)碼對象
*
* Method[] getMethods()
* 獲取該字節(jié)碼對象中所有public修飾的成員方法
*
* 枚舉中的常用方法:
* public static Week[] values()
* 獲取所有的枚舉常量,并把所有的枚舉常量封裝到一個數(shù)組中返回
* public static Week.valueOf(String str)
* public final String name() 返回此枚舉常量的名稱,在其枚舉聲明中對其進(jìn)行聲明。
*
*/
public class WeekDemo {
@Test
public void testMethod() {
System.out.println(Week.class.getSuperclass());//class java.lang.Enum
}
@Test
public void testMethod02() {
//1.利用字節(jié)碼對象獲取所有的成員方法
Method[] methods = Week.class.getMethods();
//2.遍歷methods數(shù)組
for (Method method : methods) {
System.out.println(method);
}
}
@Test
public void testMethod03() {
Week[] weeks = Week.values();
for (Week week : weeks) {
System.out.println(week);
}
}
@Test
public void testMethod04() {
System.out.println(Week.valueOf("MONDAY"));
System.out.println(Week.valueOf("MONDAY")==Week.MONDAY);//true
}
@Test
public void testMethod05() {
System.out.println(Week.FRIDAY.name());//跟toString原理相同
System.out.println(Week.FRIDAY);
System.out.println(Week.FRIDAY.toString());
}
}
文章來源地址http://www.zghlxwxcb.cn/news/detail-753787.html
文章來源:http://www.zghlxwxcb.cn/news/detail-753787.html
到了這里,關(guān)于Java中的單元測試,反射和枚舉的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!