Unit testing
It is to write test code to test the correctness of the smallest functional unit (method).
How did we perform unit testing before? What’s the problem?
Junit unit testing framework
It can be used to test methods. It is open sourced by Junit.
Specific steps
Common annotations of Junit framework
public class StringUtilTest { @Test @Before public void testPrintNumber(){ StringUtil.printNumber("haha"); StringUtil.printNumber(null); } @Test public void testGetMaxIndex(){ int sum = new StringUtil().getMaxIndex("Batman won't hit you"); System.out.println(sum); Assert.assertEquals("warning,warning",6,sum); } @Test @After public void testPrint(){ System.err.println("End"); } }
Reflection
Reflection is: loading a class and allowing programmatic dissection of various components in the class (member variables, methods, constructors, etc.).
What does reflection teach?
Three ways to obtain Class objects
1. Directly use class name.class to obtain: Class c1 = class name.class
2. Call the method provided by Class: Class c2 = Class.forName(“Full class name”)
3. Call the method provided by Object: Class c3 = object.getClass()
public class Demo1 { @Test public void testDemo01() throws ClassNotFoundException { Class catClass = Cat.class; System.out.println(catClass.getName()); Class aClass = Class.forName("com.itheima.b_reflection.Cat"); System.out.println(aClass); Class aClass1 = new Cat().getClass(); System.out.println(aClass1); } }
Get the constructor of the class
/* Get the constructor [the following is the method of Class] Constructor<?>[] getConstructors() gets all public constructors (only public modified ones can be obtained) Constructor<?>[] getDeclaredConstructors() Get all constructors (you can get them as long as they exist) Constructor<T> getConstructor(Class<?>... parameterTypes) Gets a public constructor (only public-modified ones can be obtained) Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) Get a certain constructor (you can get it as long as it exists) Use a constructor (create an object) [The following is the method of Constructor] T newInstance(Object... initArgs) calls the constructor represented by this constructor object, passes in the parameters, completes the initialization of the object and returns public void setAccessible(boolean flag) is set to true, which means that checking access control (violent reflection) is prohibited Notice If you want to use private modified constructor reflection to create an object, violent reflection is required (prohibiting the JVM from checking the access permissions of the constructor) */ public class Demo2 { @Test public void testConstructor() throws NoSuchMethodException { Class<Cat> clazz = Cat.class; //Get all constructors (public) Constructor[] constructors = clazz.getConstructors(); for (Constructor constructor : constructors) { System.out.println(constructor); } Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors(); for (Constructor<?> declaredConstructor : declaredConstructors) { System.out.println(declaredConstructor); } System.out.println("===================================="); Constructor<Cat> constructor = clazz.getConstructor(); System.out.println(constructor); System.out.println("==============================="); Constructor<Cat> declaredConstructor = clazz.getDeclaredConstructor(String.class, int.class); System.out.println("Method name:" + declaredConstructor.getName() + "Number of parameters:" + declaredConstructor.getParameterCount()); } @Test public void testNew() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { Class calazz = Cat.class; Constructor declaredConstructor = calazz.getDeclaredConstructor(String.class, int.class); declaredConstructor.setAccessible(true); Cat Garfield = (Cat)declaredConstructor.newInstance("Garfield", 3); System.out.println(Garfield); } }
Get the member variables of the class
public class Demo3 { @Test public void testField() throws NoSuchFieldException { Class<Cat> catClass = Cat.class; //Get all public member variables of the class (only public modified ones can be obtained) Field[] fields = catClass.getFields(); for (Field field : fields) { System.out.println(field); } System.out.println("==============="); //Get all member variables of the class Field[] declaredFields = catClass.getDeclaredFields(); for (Field declaredField : declaredFields) { System.out.println(declaredField.getName() + declaredField.getType()); } System.out.println("===================="); Field a = catClass.getField("a");//Get the member variables of a certain class, you can get them as long as they exist System.out.println(a); Field age = catClass.getDeclaredField("age"); System.out.println(age); } @Test public void test2() throws NoSuchFieldException, IllegalAccessException { Classclazz = Cat.class; Cat cat = new Cat(); // System.out.println(cat); Field age = clazz.getDeclaredField("age"); Field name = clazz.getDeclaredField("name"); //violent reflection age.setAccessible(true); name.setAccessible(true); age.set(cat,5); name.set(cat,"haha"); System.out.println(cat); //Get value Object o = age.get(cat); System.out.println(o); } }
Get the member methods of the class
/* Get member method [provided by Class] Method[] getMethods() gets all the public member methods of the class (only public modified ones can be obtained) Method[] getDeclaredMethods() Gets all member methods of the class (you can get them as long as they exist) Method getMethod(String name, Class<?>... parameterTypes) Gets a public member method of the class (only public modified ones can be obtained) Method getDeclaredMethod(String name, Class<?>... parameterTypes) Gets a certain member method of the class (you can get it as long as it exists) Use member methods (execution methods) [provided by Method] public Object invoke(Object obj, Object... args) triggers the execution of this method on an object. public void setAccessible(boolean flag) is set to true, which means that checking access control (violent reflection) is prohibited Notice If you want to use private modified member methods, you need violent reflection */ public class Demo4 { @Test public void testMethods() throws NoSuchMethodException { Class<Cat> catClass = Cat.class; Method[] methods = catClass.getMethods(); for (Method method : methods) { System.out.println("Method name:" + method.getName() + "Return value type:" + method.getReturnType()); } System.out.println("============================"); Method[] declaredMethods = catClass.getDeclaredMethods(); for (Method declaredMethod : declaredMethods) { System.out.println("Method name:" + declaredMethod.getName() + "Return value type" + declaredMethod.getReturnType()); } System.out.println("============================"); Method eat = catClass.getDeclaredMethod("eat"); System.out.println("Method name:" + eat.getName() + "Return value type" + eat.getReturnType()); System.out.println("============================"); Method eat1 = catClass.getDeclaredMethod("eat", String.class); System.out.println("Method name:" + eat1.getName() + "Return value type" + eat1.getReturnType()); } @Test public void tese2() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { Class<Cat> clazz = Cat.class; Method eat = clazz.getDeclaredMethod("eat", String.class); eat.setAccessible(true); Cat cat = new Cat(); Object invoke = eat.invoke(cat, ""); System.out.println(invoke); } }
Case:
/* reflection case For any object, the framework can print the field name and corresponding value of the object on the console. */ public class Demo5 { public static void main(String[] args) { //1. Prepare two objects Student student = new Student("Liu Yan", 40, 'Female', 167.5, "Actress"); Teacher teacher = new Teacher("BoNiu", 6000); //2. Call method print(student); } public static void print(Object o) { try { Class clazz = o.getClass(); Field[] declaredFields = clazz.getDeclaredFields(); for (Field declaredField : declaredFields) { declaredField.setAccessible(true); String name = declaredField.getName(); Object o1 = declaredField.get(o); System.out.println(name + o1); } }catch (Exception e){ } } } class Student{ public Student(String name, int age, char sex, double height, String hobby) { this.name = name; this.age = age; this.sex = sex; this.height = height; this.hobby = hobby; } private String name; private int age; private char sex; private double height; private String hobby; } class Teacher { public Teacher(String name, double salary) { this.name = name; this.salary = salary; } private String name; private double salary; }
The role of reflection
Annotations
Meta-annotation
Refers to: annotations that modify annotations.
Annotation parser
It is to determine whether there are annotations on the class, method, and member variables, and parse the content in the annotations.
How to parse annotations
public class ClassNameCheckParser { public static void checkClassName(){ //1. Store classes that do not comply with specifications ArrayList<String> list = new ArrayList<>(); //2. Get all classes under the specified package Set<Class> clazzSet = ClassUtil.getClasses("com.itheima.c_annotation.example"); //3. Traverse the set collection to find the class annotated with @ClassNameCheck' for (Class clazz : clazzSet) { //Determine whether there is an annotation on a certain class if(clazz.isAnnotationPresent(ClassNameCheck.class)){ //Get the class name String simpleName = clazz.getSimpleName(); //Check if the class name starts with Heima if(!simpleName.startsWith("Hei")){ list.add(simpleName); } } } //Determine whether there are any in the collection that do not meet the specifications, and if so, save them directly if(list.size() > 0) { System.out.println("The following class name does not comply with the specification"); for (String name : list) { System.out.println(name); } throw new RuntimeException("Program terminated"); } } }