一、Junit单元测试
1.Junit介绍
概述:Junit是一个单元测试框架,可以代替main方法去执行其他的方法
作用:单独执行一个方法,测试该方法是否能跑通
注意:Junit是第三方工具,所以使用之前需要导入jar包
2.Junit的基本使用(重点)
导入Junit的jar包
定义一个方法,在方法上写注解:@Test
执行方法:
a点击该方法的左边的绿色按钮,点击执行run执行->单独执行一个指定的方法
b:如果想要执行所有带@Test的方法,点击类名左边的绿色按钮,点击run执行->执行当前类中所有带@Test的方法
Junit的注意事项
@Test不能修饰static方法
@Test不能修饰带参数的方法
@Test不能修饰带返回值的方法
import org.junit.Test;public class Demo01Junit {@Testpublic void add(){System.out.println("我是@Test的执行add方法");}@Testpublic void delete(){System.out.println("我是@Test的执行delete方法");}
}
Junit相关注解
@Before:在@Test前执行,有多少@Test执行,@Before就执行多少次->都是用作初始化一些数据
@After:在@Test之后执行,有多少个@Test执行,@After就执行多少次->用作释放资源使用
import org.junit.After;
import org.junit.Before;
import org.junit.Test;public class Demo02Junit {@Testpublic void add(){System.out.println("我是@Test的执行add方法");}@Testpublic void delete(){System.out.println("我是@Test的执行delete方法");}@Beforepublic void methodBefore(){System.out.println("我是Before执行的方法");}@Afterpublic void methodAfter(){System.out.println("我是After执行的方法");}
}
其他注解:(了解)
@Beforeclass:在@Test之前执行,只执行一次,可以修饰静态方法
@AfterClass:在@Test之后执行,只执行一次,可以修饰静态方法
二、反射
1.介绍
反射的概述:解剖class对象的一个技术
问题:能解剖class对象的啥呢?
a:解剖出成员变量:赋值
b:解剖出成员方法:调用
c:解剖出构造方法:new对象
用反射的好处:让代码变得更通用,更灵活
怎么学反射?
a:将反射看成是一套API来学
b:同伙案例,体会好处
问题:玩反射,最开始的一步是干啥?
获取class对象
class对象:是class文件对应的对象
Class类:描述class的对象的类叫做class类
2.反射之获取class对象
方式一:调用object中的getclass方法:
Class<?> getClass()
方式二:不管是基本类型还是引用类型,jvm都为其提供了一个静态成员:class
方式三:Class类中的静态方法:
Static Class<?> forName(String className)
ClassName:传递的是类的全限定名(包名,类名)
import org.junit.Test;public class Demo01GetClass {@Testpublic void get1() throws Exception{/* 1.调用object中的getclass方法:Class<?> getClass()*/Person person = new Person();Class<? extends Person> aClass = person.getClass();System.out.println(aClass);System.out.println("=====================");
//2.不管是基本类型还是引用类型,jvm都为其提供了一个静态成员:classClass<Person> aClass1 = Person.class;System.out.println(aClass1);System.out.println("===========");/* 3.Class类中的静态方法:Static Class<?> forName(String className)ClassName:传递的是类的全限定名(包名,类名)*/Class<?> aClass2 = Class.forName("com.ykm.b_reflect.Person");System.out.println(aClass2);System.out.println(aClass1==aClass2);}
}
三种获取class对象的方式最通用的一种
方式三:Class类中的静态方法:
Static Class<?> forName(String className)
ClassName:传递的是类的全限定名(包名,类名)
原因:参数String形式可以和properties文件结合使用
开发中最常用的是哪一种
直接类名.class->最方便使用
3.获取Class对象中的构造方法
(API)找对象方法获取功能
获取所有public的构造方法
Class类中的方法:
Constructor<?>[] getConstructors() ->获取所有public的构造
import java.lang.reflect.Constructor;public class Demo03GetConstructor {public static void main(String[] args) {//获取Class对象Class<Person> aClass = Person.class;//获取所有public的构造Constructor<?>[] constructors = aClass.getConstructors();for (Constructor<?> constructor : constructors) {System.out.println(constructor);}}
}
4.获取空参构造_public
Constructor<T> getConstructor(Class<?>.....parameterTypes) ->获取指定的public的构造
parameterTypes:参数类型,可变参数,可以传0个或者多个参数
如果获取的是空参构造:参数不写
如果是获取的是有参构造:参数写参数类型的Class对象
Constructor类中的方法:
NewInstance(Object...intargs)->创建对象
.intargs:传递的是构造方法中的实参
如果根据无参构造new对象,initargs不写了
如果根据有参构造new对象,initargs传递实参
import java.lang.reflect.Constructor;public class Demo04GetConstructor {public static void main(String[] args) throws Exception{//获取Class对象Class<Person> aClass = Person.class;Constructor<Person> constructor = aClass.getConstructor();System.out.println(constructor);/** 好比是person person=new person()* */Person person = constructor.newInstance();System.out.println(person);}
}
5.利用空参构造创建对象的快捷方式_public
Class类中的方法:
T newInstance()->.根据空参构造创建对象
前提:被反射的类中必须有public的空参构造
import java.lang.reflect.Constructor;public class Demo05GetConstructor {public static void main(String[] args) throws Exception{//获取Class对象Class<Person> aClass = Person.class;Constructor<Person> constructor = aClass.getConstructor(String.class, Integer.class);System.out.println(constructor);//创建对象Person person = constructor.newInstance("名", 18);System.out.println(person);}
}
6.利用反射获取有参构造并创建对象_public
Class类中的方法:
Constructor<T> getConstructor(class<?>.......parameterTypes)->获取指定的public的构造
parameterTypes:可变参数,可以传递0个或者多个参数
如果获取的是空参构造:参数不用写
如果获取的是有参构造:参数写参数类型的class对象
Constructor类中的方法:
T newInstance(Object.....initargs)->创建对象
initargs:传递的是构造方法的实参
如果根据无参构造new对象,initargs不写了
如果根据有参构造new对象,initargs传递实参
import java.lang.reflect.Constructor;public class Demo06GetConstructor {public static void main(String[] args) {Class<Person> aClass = Person.class;Constructor<?>[] dc = aClass.getDeclaredConstructors();for (Constructor<?> constructor : dc) {System.out.println(constructor);}}
}
7.利用反射获取私有构造(暴力反射)
Constructor<?>[] getDeclaredConstructors()获取所有的构造方法,包括private
Constructor<T> getDeclaredConstructor(类<?>......parameterTypes)->获取指定构造,包括private
parameterTypes:参数类型的class对象
Constructor有一个父类叫做AccessibleObject,里面有一个方法
void setAccessible(boolean flag)->.修改访问权限
flag为true:解除私有权限
import java.lang.reflect.Constructor;public class Demo07GetConstructor {public static void main(String[] args)throws Exception {Class<Person> aClass = Person.class;Constructor<Person> dc = aClass.getDeclaredConstructor(String.class);dc.setAccessible(true);//接触私有权限->暴力反射Person person = dc.newInstance("名");System.out.println(person);}
}
8.反射成员方法
(1)利用反射获取所有成员方法_public
Class类中方法:
Method[] getMethods()->获取所有public的方法,包括父类中的public方法
(2)反射之获取方法(有参,无参)_public
Class类中的方法:
Method getMethod(String name,Class<?>.....parameterTypes)获取指定的public的成员方法
Name:传递方法名
ParameterTypes:方法参数类型的class对象
调用方法:Method对象中的方法
Object invoke(Object obj,Object.....args)->执行方法
Obj:根据构造new出来的对象
Args:方法实参->如果有参数,直接传递实参;否则不用传
9.反射成员变量
Class类中的方法:
Filed[] getFields()->获取所有public的属性
Filed[] getDeclaredFields()->获取所有属性,包括private的
获取指定的属性
Class类中的方法:
Filed getField(String name)->获取指定public的属性
Filed getDeclaredField(String name)->获取指定属性,包括private的
Field类中的方法:
Void set(Object obj,Object value)->为属性赋值,相当一Javabean中的set方法
Obj:对象
Value:赋予的值
Object get(Object obj)->获取属性值
Obj:对象
import java.lang.reflect.Field;public class Demo08GetFiled {public static void main(String[] args)throws Exception {// method01();// method02();method03();}/*Filed getDeclaredField(String name)->获取指定属性,包括private的* */private static void method03() throws Exception{Class<Student> studentClass = Student.class;Student student = studentClass.newInstance();Field name = studentClass.getDeclaredField("name");//解除私有权限name.setAccessible(true);//调用set方法赋值name.set(student,"名");//调用getObject o = name.get(student);System.out.println(o);}/**Filed getField(String name)->获取指定public的属性** */private static void method02() throws Exception{Class<Student> studentClass = Student.class;Student student = studentClass.newInstance();Field age = studentClass.getField("age");//调用set方法赋值age.set(student,10);//调用getObject o = age.get(student);System.out.println(o);}private static void method01() {Class<Student> studentClass = Student.class;Field[] fields = studentClass.getFields();for (Field field : fields) {System.out.println(field);}System.out.println("=============");Field[] df = studentClass.getDeclaredFields();for (Field field : df) {System.out.println(field);}}
}
10.反射之操作私有方法
Method[] getDeclareMethods()
Method[] getDeclareMethod(String name,类<?>.....parameterTypes)->获取执行成员方法,包括private
name:传递方法名
parameterTypes:方法参数类型的class对象
解除私有权限:void setAccessible(boolean flag)
import java.lang.reflect.Method;public class Demo09GetMethod {public static void main(String[] args) throws Exception {// method01();// method02();// method03();method04();}/** 反射指定的方法包括private* */private static void method04()throws Exception {Class<Person> aClass = Person.class;Person person = aClass.newInstance();Method eat = aClass.getDeclaredMethod("eat");eat.setAccessible(true);eat.invoke(person);}/*** 获取所有成员方法包括private* */private static void method03() {Class<Person> aClass = Person.class;Method[] dm = aClass.getDeclaredMethods();for (Method method : dm) {System.out.println(method);}}/** 获取指定的public的方法* */private static void method02() throws Exception{Class<Person> aClass = Person.class;//创建对象Person person = aClass.newInstance();Method setName = aClass.getMethod("setName", String.class);setName.invoke(person,"名");System.out.println(person);//好比调用tostring方法System.out.println("=============");Method getName = aClass.getMethod("getName");Object invoke = getName.invoke(person);System.out.println(invoke);}/** 获取所有public的方法** */private static void method01() {Class<Person> aClass = Person.class;Method[] method = aClass.getMethods();for (Method method1 : method) {System.out.println(method1);}}
}
三、注解
1.注解的介绍
引用数据类型:类 数组 接口 枚举 注解
jdk1.5版本的新特性->一个引用数据类型和类,接口,枚举是同一个层次的
作用:
说明:对代码进行说明,生成doc文档(API文档)
检查:检查文档是否符合条件 @Override(会用) @FunctionalInterface
分析:对代码进行分析,起到了代替配置文件的作用(会用)
JDK中的注解:
@Override->检测此方法是否为重写方法
jdk1.5版本,支持父类的方法重写
jdk1.6版本,支持接口的方法重写
2.注解的定义以及属性的定义格式
大家需要知道的是,咱们这里说的注解属性,其实本质上是抽象方法,但是我们按照属性来理解,好理解,因为到时候使用注解的时候,需要=为其赋值
定义:
public @interface 注解名{
}
定义属性:增强注解的作用
数据类型 属性名()->此属性没有默认值,需要在使用注解的时候为其赋值
数据类型 属性名() default 值->此属性有默认值,如果有需要,还可以二次赋值
注解中能定义什么类型的属性呢?
8种基本类型
String类型,Class类型,枚举类型,注解类型
以及以上类型的一维数组
public @interface Book {//书名String bookName();//作者String[] author();//价格int price();//数量int count() default 10;
}
注解的使用
就是为注解中的属性赋值
使用位置:类,方法,成员变量,局部变量,参数位置等
使用格式
@注解名(属性名=值,属性名=值.....)
如果属性中有数组:@注解名(属性名={元素一,元素二.......})
@Book(bookName = "水浒传",author = "施耐庵",price = 50,count = 20)
public class BookShelf {}
注解注意事项:
空注解可以直接使用->空注解就是注解中没有任何的属性
不同位置的可以使用一样的注解,但是同样的位置不能使用一样的注解
使用注解时,如果此注解中有属性,注解中的属性一定要赋值,如果有多个属性用,隔开
如果注解中的属性有数组,使用{}
如果注解中的属性值有默认值,那么我们不必要写,也不用重新赋值,反之必须协商
如果注解种只有一个属性,并且属性名叫value,那么使用注解的时候,属性名不用写,直接写值(包括单个类型,还包括数组)
注解解析的方法->AnnotatedElement接口
注解的解析:说白了就是将注解中的属性值获取出来
注解的解析涉及到的接口:AnnotatedElement接口
3.元注解
概述:元注解就是管理注解的注解
从那些方面管理呢?
a:控制注解的使用位置
控制注解是否能在类(方法、构造)上使用
b:控制注解的生命周期(如加载位置)
控制注解是否能在源码(class、内存)中出现
怎么使用
a:@Target:控制注解的使用位置
属性:ElementType[] value();
ElementType是一个枚举,里面的成员可以类名直接调用
ElementType中的成员:
TYPE:控制注解能使用在类上
FIELD:控制注解能使用在属性上
METHOD:控制注解能使用在方法上
PARAMETER:控制注解能使用在参数上
CONSTRUCTOR:控制注解能使用在构造上
LOCAL_VARIABLE:控制注解能使用在局部变量上
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;@Target({ElementType.TYPE,ElementType.METHOD})
public @interface Book {//书名String bookName();//作者String[] author();//价格int price();//数量int count() default 10;
}
四、枚举
1.介绍
概述:五大引用数据类型之一(类 数组 接口 注解 枚举)
定义:
Public enum 枚举类名{ }
所有的枚举为父类都是Enum
定义枚举值
a:枚举值特点:都是static final,但是定义的时候不要写出来,写出来报错
写完所有的枚举值之后,最后加个;枚举值名字要大写->开发习惯
b:类名直接调用
c:注意:每一个枚举值都是当前枚举类的对象
问题:枚举类中的枚举值都是什么类型的呢? 本类类型
枚举类中其他成员:构造
在枚举类中定义的构造,默认的都是private的
枚举的使用场景:表示对象的状态
public enum State {//State WEIFUKUAN=new State()//State WEIFUKUAN=new State("未付款")WEIFUKUAN("未付款"),YIFUKUAN("已付款"),WEIFAHUO("未发货"),YIFAHUO("已发货");private String name;State() {}State(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}
2.枚举的方法
方法名 | 说明 |
---|---|
String toString() | 返回枚举值的名字 |
values() | 返回所有与的枚举值 |
valueOf(String str) | 将一个字符串转成枚举类型 |
public class Test01 {public static void main(String[] args) {State weifahuo = State.WEIFAHUO;System.out.println(weifahuo.getName());System.out.println("================");String s = State.WEIFUKUAN.toString();System.out.println(s);System.out.println("=========");State[] values = State.values();for (State value : values) {System.out.println(value);}}
}