Java单元测试、反射、注解

单元测试

Junit

public class UserService {     public String login(String loginName, String password) {         if (admin.equals(loginName) && 123456.equals(password)) {             return success;         }         return 用户名或密码错误;     } }   public class UserServiceTest {     /**      * 测试方法要求:      * 1.必须public修饰      * 2.没有返回值没有参数      * 3.必须使注解@Test修饰      */     @Test     public void testLogin() {         UserService userService = new UserService();         String rs = userService.login(admin, 123456);         // 断言预期结果的正确性         /**          * 参数一:测试失败的提示信息          * 参数二:期望值          * 参数三:实际值          */         Assert.assertEquals(登录业务功能方法有误, success, rs);     } }

 

Junit常用注解

 

如Junit4,如5个注解都有,则执行顺序为@BeforeClass、@Before、@Test、@After、@AfterClass

 

反射

 

反射获取类对象

public class ReflectDemo01 {     public static void main(String[] args) throws ClassNotFoundException {         // 反射的第一步永远是先得到类的Class文件对象:字节码文件         // 1.类名.class         Class c1 = Student.class;         System.out.println(c1);              // 2.对象.getClass()         Student swk = new Student();         Class c2 = swk.getClass();         System.out.println(c2);          // 3.Class.forName(类的全限名)         Class c3 = Class.forName(Student);         System.out.println(c3);     } }

 

反射获取构造器对象

public class ReflectDemo01 {     public static void main(String[] args) throws ClassNotFoundException {         // 反射的第一步永远是先得到类的Class文件对象:字节码文件         // 1.类名.class         Class c1 = Student.class;         System.out.println(c1);          // 2.对象.getClass()         Student swk = new Student();         Class c2 = swk.getClass();         System.out.println(c2);          // 3.Class.forName(类的全限名)         Class c3 = Class.forName(Student);         System.out.println(c3);     }      @Test     public void getConstructors() {         // 1.反射第一步得到Class类对象         Class c = Student.class;          // 2.定位全部构造器,只能拿public修饰         Constructor[] cons = c.getConstructors();          // 3.遍历构造器         for (Constructor con: cons) {             System.out.println(con.getName() + ===> + con.getParameterCount());         }     }      @Test     public void getDeclaredConstructors() {         // 1.反射第一步得到Class类对象         Class c = Student.class;          // 2.定位全部构造器,只要申明了就可以拿到         Constructor[] cons = c.getDeclaredConstructors();          // 3.遍历构造器         for (Constructor con: cons) {             System.out.println(con.getName() + ===> + con.getParameterCount());         }     }      @Test     public void getDeclaredConstructor() throws NoSuchMethodException {         // 1.反射第一步得到Class类对象         Class c = Student.class;          // 2.定位全部构造器,只要申明了就可以拿到         // Constructor con = c.getDeclaredConstructor();         Constructor con = c.getDeclaredConstructor(String.class, int.class);         // 3.遍历构造器         System.out.println(con.getName() + ===> + con.getParameterCount());     } }  public class Student {     private String name;     private int age;      public Student() {     }      private Student(String name, int age) {         this.name = name;         this.age = age;     }      public String getName() {         return name;     }      public void setName(String name) {         this.name = name;     }      public int getAge() {         return age;     }      public void setAge(int age) {         this.age = age;     } }

 

反射获取构造器然后通过构造器初始化对象

 

    // 调用无参构造器得到一个类的对象返回     @Test     public void createObj01() throws Exception {         // a.反射第一步是先得到Class类对象         Class c = Student.class;         // b.定位无参数构造器对象         Constructor constructor = c.getDeclaredConstructor();         // c.通过无参数构造器初始化对象返回         constructor.setAccessible(true);         // d.通过无参数构造器初始化对象返回         Student swk = (Student) constructor.newInstance();         System.out.println(swk);     }      // 调用有参构造器得到一个类的对象返回     @Test     public void createObj02() throws Exception {         // a.反射第一步是先得到Class类对象         Class c = Student.class;         // b.定位无参数构造器对象         Constructor constructor = c.getDeclaredConstructor(String.class, int.class);          // c.通过有参数构造器初始化对象返回         Student swk = (Student) constructor.newInstance(测试, 100);         System.out.println(swk);     }

 

反射获取Field成员变量对象及赋值

    /**      * 获取全部的成员变量      * @throws Exception      */     @Test     public void createObj03() throws Exception {         // a.反射第一步是先得到Class类对象         Class c = Dog.class;         // b.获取全部申明的成员变量对象         Field[] fields = c.getDeclaredFields();         for (Field field: fields) {             System.out.println(field.getName()+);         }          Field nameF = c.getDeclaredField(name);          // c. 为这个成员变量赋值         Dog taidi = new Dog();         /**          * 参数一:被赋值的对象          * 参数二:该成员变量的值          */         nameF.setAccessible(true);         nameF.set(taidi, 勇敢的泰迪);         System.out.println(taidi);          String value = nameF.get(taidi) + ;         System.out.println(value);     }

 

反射获取Method方法对象

    /**      * 获取所有方法对象      */     @Test     public void getDeclaredMethods() {         Class d = Dog.class;          Method[] methods = d.getDeclaredMethods();          for (Method method: methods) {             System.out.println(method.getName() + ====> + method.getParameterCount() + ===> + method.getReturnType());          }     }      /**      * 获取某个方法对象      */     @Test     public void getDeclardMethod() throws Exception {         // 1.先获取class类对象         Class c = Dog.class;         // 2.定位它的某个方法         Method run = c.getDeclaredMethod(run);         // 3.触发方法执行         Dog jinmao = new Dog();         run.invoke(jinmao); // 触发jinMao对象的run()方法执行          /**          * 参数一:方法名称          * 参数二:方法的参数个数和类型(可变参数)          */         Method eat = c.getDeclaredMethod(eat, String.class);         eat.setAccessible(true);         /**          * 参数一:被触发方法所在的对象          * 参数二:方法需要的入参值          */         eat.invoke(jinmao, 肉);         System.out.println();     }  public class Dog {     private void eat() {         System.out.println(狗吃骨头);     }      private void eat(String name) {         System.out.println(狗吃 + name);     }      public void run() {         System.out.println(狗在跑);     } }

 

反射破坏类的封装性与泛型的约束性

    @Test     public void getDeclardMethod1() throws Exception {         // 泛型只能工作在编译阶段,运行阶段泛型就消失了         // 反射工作在运行阶段         List<Double> scores = new ArrayList<>();         scores.add(24.1);         scores.add(123.4);          // 拓展:通过反射暴力注入一个其它类型数据         Class c = scores.getClass();         // 从ArrayList的class对象中定位add方法         Method add = c.getDeclaredMethod(add, Object.class);         // 出发scores集合对象中的add执行(运行阶段,泛型不能约束了)         add.invoke(scores, 波仔);         System.out.println(scores);     }

 

反射的作用

    public static void main(String[] args) throws ClassNotFoundException {         Dog dog = new Dog(haha, 15, 红);         MyBatis.save(dog);     }  public class Dog {     private String name;     private int age;     private String color;      public Dog(String name, int age, String color) {         this.name = name;         this.age = age;         this.color = color;     }      public Dog() {     }      public String getName() {         return name;     }      public void setName(String name) {         this.name = name;     }      public int getAge() {         return age;     }      public void setAge(int age) {         this.age = age;     }      public String getColor() {         return color;     }      public void setColor(String color) {         this.color = color;     } }   import java.io.FileOutputStream; import java.io.PrintStream; import java.lang.reflect.Field;  public class MyBatis {     // 提供一个方法:可以保存一切对象数据的字段和具体值     public static void save(Object obj) {         try (                 PrintStream ps = new PrintStream(new FileOutputStream(反射/src/test.txt, true));         ) {             // 1.先得到对象的Class文件对象             Class c = obj.getClass();             // 2.定位它的全部成员变量             Field[] fields = c.getDeclaredFields();             // 3.遍历这些字段并取值             for (Field field: fields) {                 // 字段名称                 String name = field.getName();                 // 字段的值                 field.setAccessible(true); // 暴力反射                 String value = field.get(obj) + ;                 ps.println(name + = + value);             }         }catch (Exception e) {             e.printStackTrace();         }     } }

 

 

注解

 

自定义注解

 

注解的属性

 

注解的特殊属性

 

元注解——是用在自定义注解上的注解

 

 

 

 

 

 注解的解析

 

 

@Book(value=test1, authors = {1, 2}, price = 5.1) public class MyBook {     public static void main(String[] args) throws NoSuchMethodException {         // 1.定位Class类对象         Class c = BookStore.class;         // 2.判断这个类上是否使用了某个注解         if (c.isAnnotationPresent(Book.class)) {             // 3.获取这个注解对象             Book book = (Book) c.getDeclaredAnnotation(Book.class);             System.out.println(book.value());             System.out.println(book.price());         }          Method run = c.getDeclaredMethod(run);          // 2.判断这个方法上是否使用了某个注解         if (run.isAnnotationPresent(Book.class)) {             // 3.获取这个注解对象             Book book = (Book) run.getDeclaredAnnotation(Book.class);             System.out.println(book.value());             System.out.println(book.price());         }     } }  @Book(value = Java基础精通, price = 50, authors = {脖子, 哈哈}) class BookStore {     @Book(value = Java基础精通1, price = 500, authors = {脖1子, 哈2哈})     public void run() {      } } // 自定义一个注解 @Target({ElementType.METHOD, ElementType.FIELD, ElementType.TYPE}) // 申明只能注解方法与成员变量与类     @Retention(RetentionPolicy.RUNTIME) @interface Book {     String value();     String[] authors();     double price();     String address() default 广州; }

 

注解模拟Junit框架的基本使用

@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @interface MyTest {  }  MyBook t = new MyBook(); Class d = MyBook.class; // 2.获取类中全部方法对象 Method[] methods = d.getDeclaredMethods(); for (Method method: methods) {   if (method.isAnnotationPresent(MyTest.class)) {     // 触发此方法执行     method.invoke(t);
    }
} @MyTest public void test01() {   System.out.println(====test01====); } @MyTest public void test02() {   System.out.println(====test02====); } @MyTest public void test03() {   System.out.println(====test03====); }