Basic use of Junit unit testing:
1. Add an annotation @Test
to the method to be executed 2. The annotation will report an error and the solution is ctrl+1 add junit
3. Select the method to be executed Right-click on the method and run as --> junit Test
Execute multiple methods at once: Right-click on the selected class and run as --> Junit Test
Notes on Junit unit testing:
1 .Methods without the @Test annotation cannot be run using Junit
2.Junit can only run empty parameter methods with the modifier public and return value type void
Annotations related to unit testing
@Test: Unit test, you can execute a method separately
@Before: Executed before the unit test @Test can be used to obtain some resources
@After: Executed after the unit test @Test Can be used to use some resources
Note: @Before and @After cannot be executed separately to run @Test, they will automatically execute
Annotations provided after JDK1.5
@Deprecated: Indicates that it is obsolete
@Deprecated: It can be used to modify classes to represent obsolete classes, and it can also be used to modify methods to represent obsolete methods.
Obsolete classes and methods can be used, but it is not recommended because they may have defects or be better. The method replaces the annotations provided after
@Override: a method used to test whether the method is overridden
In JDK1.5, @Override can only detect class inheritance and class rewriting. Method
JDK1.6 and above, @Override can detect both the class inheritance class rewriting method and the class implementation interface rewriting method
Annotations provided after JDK1.5
@SuppressWarnings : Indicates suppressing warnings (not allowing warnings to be displayed)
@SuppressWarnings: When using it, you must be clear about which warning you want to suppress
@SuppressWarnings (parameter): The parameter is a string array
If you only write one parameter {} can be ignored. If there are multiple parameters, {} must be used. Use commas to separate multiple parameters.
String[] a = {"ac","ds"}
The warnings that can be suppressed are:
rawtypes, ignore type safety
unchecked ignore safety check
unused ignore unused
deprecation ignore obsolescence
null ignore null pointer
serial ignore serial number
all ignore all
Comments Scope: can be defined on the class, method, code
The same annotation can only be used once at the same location
Custom annotation: use the keyword @interface
to define the class: class
Define the interface: interface
Define the enumeration: enum (elimination)
Define the annotation: @interface
Define the format of the annotation:
Modifier @interface Annotation name {
Annotated Attributes; (can be present or not)
Define annotations containing attributes:
Attributes are equivalent to member variables and member methods in classes
Definition format of attributes:
Modifier return value type (data type) Attribute name () [default attribute value]
Modifier: fixed format (similar to interface) public abstract It is recommended to write enhanced reading lines whether you write it or not
Return value type: basic data type (8 types in 4 categories) )String type Class type enumeration annotation One-dimensional array of the above type
[default attribute value]: [] Optional attributes can give a default value or not give a default value
int a; int a = 10 ;
1 public @interface MyAnnotation02 { 2 //基本数据类型(4类8种) 3 public abstract int a() default 10; 4 //String类型 5 public abstract String s(); 6 //Class类型 7 public abstract Class clazz(); 8 //枚举 9 public abstract Color c();10 //注解11 public abstract MyAnnotation01 myanno01();12 //以上类型的一维数组13 public abstract String[] arr();14 }15 16 enum Color{17 GREEN,18 RED19 /*20 * public static final Color GREEN = new Color();21 * public static final Color RED = new Color();22 */23 }
Define an annotation containing attributes
This annotation has only one attribute named value
Meta-annotation: JDK used to modify custom annotations The annotations provided
@Retention is used to determine the declaration period of the modified custom annotation
The attribute of the Retention annotation is an enumeration RetentionPolicy (the enumeration has 3 attributes SOURCE, CLASS, RUNTIME)
Function: Instruction How long should the annotation type annotation be retained?
If there is no Retention annotation in the annotation type declaration, the retention policy defaults to RetentionPolicy.CLASS
RetentionPolicy.SOURCE The modified annotation can only exist in the source code, not the bytecode class. Purpose: Provided to the compiler.
RetentionPolicy.CLASS modified annotations can only exist in source code and bytecode, not in runtime memory. Purpose: JVM java virtual machine uses
RetentionPolicy.RUNTIME modified annotations exist in source code, bytecode, and memory (runtime). Purpose: Replace xml configuration
@Target is used to determine the usage location of the modified custom annotation
The attribute of the Target annotation is an enumeration ElementType (commonly used attributes TYPE, CONSTRUCTOR....)
Function: Indicates the kind of program element to which the annotation type applies.
If no Target meta-annotation is present in the annotation type declaration, the declared type can be used on any program element.
ElementType.TYPE modified class, interface
ElementType.CONSTRUCTOR modified structure
ElementType.METHOD modified method
ElementType.FIELD modified field
1 @Retention(RetentionPolicy.RUNTIME)2 @Target({ElementType.CONSTRUCTOR,ElementType.FIELD,ElementType.METHOD,ElementType.TYPE})3 public @interface MyAnnotation03 {4 public abstract int value();5 }
使用自定义注解:
格式:@自定义注解的名字(属性名= 属性值 ,属性名=属性值)
注意:
1.自定义注解没有属性,可以直接使用-->@自定义注解的名字
2.自定义注解有属性 使用的时候 必须使用键值对的方式 给所有属性赋值 才能使用 有默认值的属性可以不用赋值
3.如果注释的属性是一个数组 赋值的时候只有一个值可以省略{} 赋值多个必须写出{}
4.注解的使用范围 可以用来修饰类 方法 构造方法 变量
5.使用自定义注解 如果只有一个属性 名字叫value 赋值的时候value可以省略不写
6.一个对象上(修饰类, 方法,构造方法,变量)注解只能使用一次 不能重复使用
自定义注解的解析:使用自定义注解 获取自定义注解的属性值
和解析有关的接口:
java.lang.reflect.AnnotatedElement接口
所有已知实现类:AccessibleObject Class Constructor Field Method Package
接口中的方法:
boolean isAnnotationPresent(Class annotationClass)
如果指定类型的注释存在于此元素上,则返回 true,否则返回 false。
判断(Constructor, Field, Method...)有没有指定的注解
参数:注解的class文件对象,可以传递MyAnnotation03.class(String.class,int.class)
T getAnnotation(Class
如果存在该元素的指定类型的注释,则返回这些注释,否则返回 null。
获取(Constructor, Field, Method...)上的注解,参数传递的是哪个注解的class文件对象,就获取哪个注解
参数:注解的class文件对象,可以传递MyAnnotation03.class
使用步骤:
1.定义一个方法,使用自定义注解
2.使用反射技术获取本类的class文件对象
3.使用反射技术获取类中所有的方法
4.遍历包含所有方法的数组,获取每一个方法
5.使用isAnnotationPresent判断该方法上是否包含传递参数的注解
6.如果方法上包含注解,使用getAnnotation获取方法上的注解
7.使用属性的名字,获取属性值
1 public class UseMyAnnotation02 { 2 //1.定义一个方法,使用自定义注解 3 @MyAnnotation03(value=10) 4 public void method(){ 5 6 } 7 8 @Test 9 public void test(){10 //2.使用反射技术获取本类的class文件对象11 Class clazz = UseMyAnnotation02.class;12 //3.使用反射技术获取类中所有的方法13 Method[] methods = clazz.getMethods();14 //4.遍历包含所有方法的数组,获取每一个方法15 for (Method method : methods) {16 String methodName = method.getName();17 //5.使用isAnnotationPresent判断该方法上是否包含传递参数的注解18 boolean b = method.isAnnotationPresent(MyAnnotation03.class);19 if(b){20 System.out.println(methodName+":"+b);21 //6.如果方法上包含注解,使用getAnnotation获取方法上的注解22 MyAnnotation03 myAnno = method.getAnnotation(MyAnnotation03.class);23 //7.使用属性的名字,获取属性值24 int v = myAnno.value();25 System.out.println(v);26 }27 }28 }29 }
类加载器:把class文件加载到内存中 并生成一个class文件对象
加载器的组成:
Bootstrap ClassLoader 引导(根)类加载器
也被称为引导类加载器 负责java核心类的加载
Extension ClassLoader 扩展类加载器
负责人JRE的扩展目录中的jar包的加载
在JDK中JRE的lib目录下井ext目录
AppClassLoader 应用类加载器
负责在JVM启动时加载来自java命令的class文件 以及classpath环境变量
所指定的jar包和类路径
自定义的类型Person; commons-io-2.4.jar
类加载器的继承关系:
AppClassLoader extends ExtClassLoader extends Bootstrap ClassLoader extends ClassLoader
和类加载器有关的方法:
Class类中的方法:
ClassLoader getClassLoader() 返回该类的类加载器。
ClassLoader类中的方法:
ClassLoader getParent() 返回委托的父类加载器。
1 public class DemoClassLoader { 2 @Test 3 public void show01(){ 4 //获取应用类加载器 5 ClassLoader loader = DemoClassLoader.class.getClassLoader(); 6 System.out.println(loader);//sun.misc.Launcher$AppClassLoader@5fcf29 7 8 loader = loader.getParent(); 9 System.out.println(loader);//sun.misc.Launcher$ExtClassLoader@5fcf2910 11 loader = loader.getParent();12 System.out.println(loader);//根类加载器由c/c++编写,没有相关的类描述,返回null13 }14 15 @Test16 public void app(){17 //获取应用类加载器18 ClassLoader loader = DemoClassLoader.class.getClassLoader();19 System.out.println(loader);//sun.misc.Launcher$AppClassLoader@5fcf2920 }21 22 @Test23 public void ext(){24 //获取扩展类加载器25 /*26 * 扩展包中的类,不支持使用27 * 想使用必须设置访问权限28 * sun/**29 */30 ClassLoader loader = SunEC.class.getClassLoader();31 System.out.println(loader);//sun.misc.Launcher$ExtClassLoader@19b1de32 }33 34 @Test35 public void boot(){36 ClassLoader loader = String.class.getClassLoader();37 System.out.println(loader);//null38 }39 }
JDK动态代理:只能代理接口
java.util.collections集合的工具类
Collections集合的工具类的静态方法
static
返回指定列表的不可修改视图
传递一个List集合返回一个被代理的List集合
unmodifiableList方法就是一个代理方法,代理List集合
如果调用size get方法 没有对集合进行修改 则允许执行
如果调用add remove set 对集合进行了修改,则抛出异常不让方法执行
会抛出UnsupportedOperationException:不支持操作异常
1 public class Demo01Proxy { 2 @Test 3 public void show(){ 4 List<String> list = new ArrayList<String>(); 5 list.add("a"); 6 list.add("b"); 7 8 //调用Collections中的方法unmodifiableList 9 list = Collections.unmodifiableList(list);10 String s = list.get(0);11 System.out.println(s);12 13 System.out.println(list.size());14 15 //list.add("c");16 //list.remove(0);17 }18 }
创建接口InvocationHandler的实现类
重写接口中的方法invoke 对集合的方法进行判断
如果调用size get方法 没有对集合进行修改 则允许执行
如果调用add remove set 对集合进行了修改 则抛出异常不让方法执行
Object invoke(Object proxy,Method method,Object[] args)在代理实例上处理方法调用并返回结果
参数:
Object proxy:内部会使用反射创建一个代理人对象,和我们无关
Method method:内部会使用反射获取到执行List集合的方法(size,get,....)
Object[] args:内部会使用反射获取到调用集合方法的参数
返回值:
Object:调用List集合的方法的返回值
注意事项:
代理的是List集合,必须把被代理的集合传递到实现类中,为了保证代理的始终是同一个List集合
在成员位置创建一个List集合
使用带参数构造给集合赋值
1 public class InvocationHandlerImpl implements InvocationHandler{ 2 private List<String> list; public InvocationHandlerImpl(List<String> list) { 5 this.list = list; 6 } 7 8 @Override 9 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {10 //获取方法的名字11 String mehtodName = method.getName();12 //对方法的名字进行判断,如果是add,remove,set就抛出异常13 if("add".equals(mehtodName)){14 throw new UnsupportedOperationException("add no run");15 } if("remove".equals(mehtodName)){18 throw new UnsupportedOperationException("remove no run");19 } if("set".equals(mehtodName)){22 throw new UnsupportedOperationException("set no run");23 } //如果是size,get执行方法25 Object obj = method.invoke(list, args);26 return obj;27 } }
1 /* 2 * 动态代理综合案例: 3 * 需求: 4 * 模拟Collections.unmodifiableList(list); 5 * 传递List,返回List 6 * 调用List方法的时候,通过我的代理类中的方法 invoke, 7 * 如果调用size,get方法,没有对集合进行修改,则允许执行 8 * 如果调用add,remove,set,对集合进行了修改,则抛出异常不让方法执行 9 * 会抛出UnsupportedOperationException:不支持操作异常10 * 实现步骤:11 * 1.模拟unmodifiableList方法,定义一个代理的方法proxyList,参数传递List集合,返回被代理后的List集合12 * 2.在proxyList方法内部实现动态代理13 * java.lang.reflect.Proxy:提供了和动态代理有关的方法14 * static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 15 * 返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。 16 * 参数:17 * ClassLoader loader:传递类加载器,加载类到内存中,创建class文件对象;可以传递本类的类加载器18 * Class<?>[] interfaces:传递ArrayList实现的接口List/Collection的Class文件对象19 * InvocationHandler h:创建一个InvocationHandler的实现类,重写接口中的方法invoke,对集合的方法进行判断20 * 如果调用size,get方法,没有对集合进行修改,则允许执行21 * 如果调用add,remove,set,对集合进行了修改,则抛出异常不让方法执行22 * 返回值类型:23 * Object:返回被代理后的List集合24 */25 @SuppressWarnings("all")26 public class Demo02Proxy {27 /*28 * 1.模拟unmodifiableList方法,定义一个代理的方法proxyList,参数传递List集合,返回被代理后的List集合29 */30 public static List<String> proxyList(List<String> list){31 //2.在proxyList方法内部实现动态代理,调用Proxy类中的方法newProxyInstance32 List<String> proxyList = (List<String>) Proxy.newProxyInstance(Demo02Proxy.class.getClassLoader(),33 list.getClass().getInterfaces(), new InvocationHandlerImpl(list));34 return proxyList;35 } /* * 1.模拟unmodifiableList方法,定义一个代理的方法proxyList,参数传递List集合,返回被代理后的List集合39 */40 public static List<String> proxyList02(final List<String> list){41 //2.在proxyList方法内部实现动态代理,调用Proxy类中的方法newProxyInstance42 List<String> proxyList = (List<String>) Proxy.newProxyInstance(Demo02Proxy.class.getClassLoader(),43 list.getClass().getInterfaces(), new InvocationHandler() {44 @Override45 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {46 //获取方法的名字47 String mehtodName = method.getName();48 //对方法的名字进行判断,如果是add,remove,set就抛出异常49 if("add".equals(mehtodName)){50 throw new UnsupportedOperationException("add no run");51 }52 53 if("remove".equals(mehtodName)){54 throw new UnsupportedOperationException("remove no run");55 } if("set".equals(mehtodName)){58 throw new UnsupportedOperationException("set no run");59 }60 //如果是size,get执行方法61 Object obj = method.invoke(list, args);62 return obj;63 }64 });65 return proxyList;66 }67 68 @Test69 public void test(){70 List<String> list = new ArrayList<String>();71 list.add("a");72 list.add("b");73 //调用代理方法proxyList传递list集合74 //list = Collections.unmodifiableList(list);75 list = Demo02Proxy.proxyList(list);76 System.out.println(list.size());77 System.out.println(list.get(0));78 //list.add("c");//UnsupportedOperationException:add no run79 //list.remove(0);//UnsupportedOperationException:remove no run80 list.set(0, "c");//UnsupportedOperationException:set no run81 }82 }
The above is the detailed content of Basic usage and precautions for Junit unit testing. For more information, please follow other related articles on the PHP Chinese website!