Junit, reflection, annotations
Junit unit test
Test categories:
Black-box testing: No need to write code, give the input value to see if the program can output the expected value
White box testing: need to write code, pay attention to the specific execution process of the program
Junit usage: white box testing
step
Define a test class (test case)
suggestion:
Test class name: the tested class name Test
Package name: xxx.xxx.xxt.est
Define the test method: can be run independently
suggestion:
Method name: the method name of the test test
return value: void
Parameter list: empty parameter
Add @Test to the method
Import junit dependent environment
critical result
red: failed
green: success
Generally we will use the assertion operation to process the result
Assert.assertEquals( expected result, operation result)
Replenish
@Before:
The decorated method will be automatically executed before the test method
@After:
The modified method will be automatically executed after the test method
package com.jx.day01_basic.test; import com.jx.day01_basic.junit.Calculator; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; public class CalculatorTest { /** * initialization method * For resource application, all test methods will be executed before execution */ @Before public void init(){ System.out.println("init......"); } /** * release resource method * Execute the method automatically after all test methods have executed */ @After public void close(){ System.out.println("close...."); } @Test public void testAdd(){ //1. Create a calculator object Calculator c=new Calculator(); //2. Call the add method int result=c.add(1,2); System.out.println("testAdd..."); // System.out.println(result); //3. Assertion I assert that this result is 3 Assert.assertEquals(3,result); } @Test public void testSub(){ Calculator c=new Calculator(); int result=c.sub(1,2); System.out.println("testSub..."); Assert.assertEquals(-1,result); } }
reflection
The soul of frame design
Framework: semi-finished software. Software development can be carried out on the basis of the framework, simplifying coding
Reflection: Encapsulate the various components of the class into other objects, which is the reflection mechanism
benefit:
These objects can be manipulated while the program is running
Can be decoupled to improve the scalability of the program
The way to get the class object
Class.forName("full class name"): Load the bytecode file into memory and return the Class object
It is mostly used in configuration files, the class name is defined in the configuration file, the file is read, and the class is loaded
Class name.class: obtained through the attribute class of the class name
It is mostly used for passing parameters
Object.getClass(): The getClass() method is defined in the Object class
It is mostly used to obtain the bytecode of the object
Summarize
The same bytecode file (*.class) will only be loaded once during a program run, no matter which method is used to obtain the Class object is the same
Class object function
Get member variables
Filed[] getFileds() Get all public modified member variables
Filed[] getFileds(String name) Get the member variable of the specified public modification
Filed[] declareFields() Get all field variables regardless of modifiers
Get constructors
get member methods
get class name
Filed: member variable
operate
Settings
void set(Object obj,Object value)
get value
get(Object obj)
Security checks that ignore access modifiers
setAccessible(true) violent reflection
public class ReflectDemo02 { public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException { //0. Get the Class object of Person Class personClass= Person.class; //1.Field[] fileds Get all public modified member variables Field[] fileds=personClass.getFields(); for (Field filed : fileds) { System.out.println(filed); } System.out.println("========="); //2.Filed getField(String name) Get the member variable of the specified public modification Field a=personClass.getField("a"); //Get the value of member variable a Person p=new Person(); Object value=a.get(p); System.out.println(value); //set the value of a a.set(p,"Zhang San"); System.out.println(p); System.out.println("====="); //Field[] declareFields get all field variables regardless of modifiers Field[] declareFields=personClass.getDeclaredFields(); for (Field declareField : declareFields) { System.out.println(declareField); } //Field getDeclaredField(String name) Field d=personClass.getDeclaredField("d"); //Security checks that ignore access modifiers d.setAccessible(true);//violent reflex Object vaule2=d.get(p); System.out.println(vaule2); } }
Constructor: construction method
create object
T newInstance(Object...initargs)
If you use the empty parameter constructor to create the object, the operation can be simplified: the newInstance method of the class object
public class ReflectDemo03 { public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { //0. Get the Class object of Person Class personClass= Person.class; //Constructor<T> getConstructor(class<?>...parameterTypes) Constructor constructor=personClass.getConstructor(String.class,int.class); System.out.println(constructor); //create object Object person=constructor.newInstance("Zhang San",23); System.out.println(person); Constructor constructor1=personClass.getConstructor(); System.out.println(constructor1); //create object Object person1=constructor1.newInstance(); System.out.println(person1); Object o=personClass.newInstance(); System.out.println(o); constructor1.setAccessible(true); } }
Method: method object
Execution method:
Object invoke(Object obj,object...args)
Get method name:
String getName: get method name
public class ReflectDemo04 { public static void main(String[] args) throws Exception { //0. Get the Class object of Person Class personClass= Person.class; //method to get the specified name Method eat_method=personClass.getMethod("eat",String.class); Person p=new Person(); //execution method eat_method.invoke(p,"vegetables"); System.out.println("........"); //Get all public modified methods Method[] methods=personClass.getMethods(); for (Method method : methods) { System.out.println(method); String name=method.getName(); System.out.println(name); } //get class name String className=personClass.getName(); System.out.println(className); } }
case:
Requirements: Write a "framework" that can help us create objects of any class and execute any method in them
accomplish:
configuration file
reflection
step:
Define the full class name of the object to be created and the method to be executed in the configuration file
Load and read configuration files in the program
Use reflection techniques to load class files into memory
create object
execution method
className=com.jx.day01_basic.domain.Person methodName=eat
package com.jx.day01_basic.reflect; import java.io.InputStream; import java.lang.reflect.Method; import java.util.Properties; public class ReflectTest { public static void main(String[] args) throws Exception { //Objects of any class can be created and any method can be executed // Person p=new Person(); // p.eat("qq"); // Student student=new Student(); // student.sleep(); //1. Load the configuration file //1.1 Create Properties object Properties pro=new Properties(); //1.2 Load the configuration file and convert it to a collection //1.2.1 Obtain the configuration file in the class directory ClassLoader classLoader=ReflectTest.class.getClassLoader(); InputStream is=classLoader.getResourceAsStream("pro.properties"); pro.load(is); //2. Get the data defined in the configuration file String className=pro.getProperty("className"); String methodName=pro.getProperty("methodName"); //3. Load the class into memory Class cls=Class.forName(className); //4. Create method object Object obj=cls.newInstance(); //5. Get the method object Method method=cls.getMethod(methodName); //execution method method.invoke(obj); } }
annotation
Function classification:
Writing documents: Generate documents through the annotations identified in the code [Generate doc documents]
Code analysis: analyze the code through the annotations identified in the code [using reflection]
Compilation check: Through the annotations marked in the code, the compiler can implement basic compilation checks [override]
Some annotations predefined in JDK
custom annotation
Using (parsing) annotations in the program
@Override: Check whether the method marked by this annotation is inherited from the parent class (interface)
@Deprecated: The content of the annotation indicates that it is outdated
@SuppressWarnings: suppress warnings
Generally pass parameters all @SuppressWarnings("all")
custom annotation
Format:
meta annotation
public @interface Annotation name { }
Nature
The essence of annotation is an interface, which inherits the Annotion interface by default
public interface MyAnno extends java.lang.annotation.Annotation { }
Attributes
Member methods that can be defined in an interface
Require:
The return value type of the property
basic data type
String
enumerate
annotation
Arrays of the above types
The attribute is defined, and it is necessary to assign a value to the attribute when using it
If you use the default keyword to give the attribute a default initial value when defining the attribute, you can not assign the attribute when using the annotation
If only one attribute needs to be assigned, and the name of the attribute is value, the value can be omitted, and the value can be defined directly
When assigning a value to an array, use {} to wrap it, if there is only one value in the array, then {} is omitted
meta annotation
Annotations used to describe annotations
@Target: Describes where the annotation can work
ElementType values:
TYPE: acts on the class
METHOD: acts on the method
FIELD: acting on member variables
@Retention: Describes the stage in which annotations are retained
@Retention(RetentionPolicy.RUNTIME): The currently described annotation will be retained in the class bytecode file and read by the JVM
@Documented: Whether the description annotation is extracted into the api document
@Interited: Describes whether the annotation is inherited by subclasses
@Target(value = {ElementType.TYPE,ElementType.METHOD,ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface MyAnno3 { }
Use annotations in the program
Get the attribute value defined in the annotation
Get the location object defined by the annotation (Class, Method, Filed)
Get the specified annotation
public class ProImpl implements Pro{ public String className(){ return "com.jx.day01_basic.annotation.Demo01"; } public String methodName(){ return "show"; } }
Call the abstract method in the annotation to get the configured attribute value
package com.jx.day01_basic.annotation; import java.lang.reflect.Method; @Pro(className = "com.jx.day01_basic.annotation.Demo01",methodName = "show") public class ReflectTest { public static void main(String[] args) throws Exception { //1. Analyzing annotations //1.1 Get the bytecode file object of this class Class<ReflectTest> reflectTestClass=ReflectTest.class; //2. Get the annotation object above //In fact, a subclass implementation object of the annotation interface is generated in memory Pro an=reflectTestClass.getAnnotation(Pro.class); //3. Call the abstract method defined in the annotation object to get the return value String className=an.className(); String methodName=an.methodName(); System.out.println(className); System.out.println(methodName); //load class Class cls=Class.forName(className); //create object Object obj=cls.newInstance(); //get method object Method method=cls.getMethod(methodName); //execution method method.invoke(obj); } }
case
package com.jx.day01_basic.annotation.demo; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.lang.management.BufferPoolMXBean; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class TestCheck { public static void main(String[] args) throws InvocationTargetException, IllegalAccessException, IOException { //1. Create a calculator object Calculator c=new Calculator(); //2. Get the bytecode file object Class cls=c.getClass(); //3. Get all methods Method[] methods=cls.getMethods(); int num=0; BufferedWriter bw=new BufferedWriter(new FileWriter("bug.txt")); for (Method method : methods) { //4. Determine whether there is a Check annotation on the method if(method.isAnnotationPresent(Check.class)){ //5. Execution try{ method.invoke(c); }catch (Exception e){ e.printStackTrace(); num++; bw.write(method+"method error"); bw.newLine(); bw.write("exception name"+e.getCause().getClass().getSimpleName()); bw.newLine(); bw.write("Abnormal"+e.getCause().getMessage()); bw.newLine(); bw.write("......."); } } } bw.write("In this test a total of"+num+"exception"); bw.flush(); bw.close(); } }
className=com.jx.day01_basic.domain.Person methodName=eat