单元测试、反射、注解、动态代理

目录

1️⃣单元测试

①单元测试的概述

⚫单元测试:就是针对最小的功能单元编写测试代码,Java程序最小的功能单元是方法,因此单元测试就是针对Java方法的测试。

②单元测试的快速入门

 ③单元测试的常用注解

 2️⃣反射

①反射概述

②反射获取类对象

③反射获取构造器对象

 ④反射获取成员变量对象

 ⑤反射获取方法对象

⑥反射的作用--绕过编译阶段为集合添加数据

⑦反射的作用--通用框架的底层原理

 3️⃣注解

4️⃣动态代理


1️⃣单元测试

①单元测试的概述

⚫单元测试:就是针对最小的功能单元编写测试代码,Java程序最小的功能单元是方法,因此单元测试就是针对Java方法的测试。

②单元测试的快速入门

 

/**
 * 测试类
 */
public class TestUserService {
    /**
        测试方法
        注意点:
             1.必须是公开的,无参数,无返回值的方法
             2.测试方法必须使用@Test注解标记
     */
    @Test
    public void testLoginName(){
        UserService userService = new UserService();
        String rs = userService.loginName("admin","123456");

        //进行预期结果的正确性测试:断言
        Assert.assertEquals("您的功能可能出现问题","登录成功",rs);
    }
    @Test
    public void testSelectNames(){
        UserService userService = new UserService();
        userService.selectNames();
    }

}

 ③单元测试的常用注解

 2️⃣反射

①反射概述

⚫反射是指对于任何一个class类,在运行的时候都可以得到这个类的全部成分

⚫可以得到这个类的构造器对象(constructor)、成员变量对象(Filed)、成员方法对象(Method)

反射的关键:

               反射的第一步就是得到编译后的class对象,人后就可以得到其所有成分。

②反射获取类对象

/*
  目标:反射第一步:获取class对象
 */
public class Test {
    public static void main(String[] args) throws Exception {
        //1.class类中的一个静态方法 :forName(全限名:包名+类名)
        Class c = Class.forName("com.study.d2_reflect_class.Student");
        System.out.println(c);

        //2.类名.class
        Class c1 = Student.class;
        System.out.println(c1);

        //3.对象.getClass()  获取对象对应类的Class对象
        Student s = new Student();
        Class c2 = s.getClass();
        System.out.println(c2);

    }
}

③反射获取构造器对象

 

public class TestStudent01 {
    //1.getConstructors:获取全部构造器(public)
    @Test
    public void getConstructors(){
        //a第一步:获取类对象
        Class c = Student.class;
        //b第二步:提取类中的全部构造器对象
        Constructor[] constructors = c.getConstructors();
        //c遍历构造器
        for (Constructor constructor : constructors) {
            System.out.println(constructor.getName() + "====>" + constructor.getParameterCount());

        }
    }

    //2.getDeclaredConstructors()  全部构造器
    @Test
    public void getDeclaredConstructors(){
        //a第一步:获取类对象
        Class c = Student.class;
        //b第二步:提取类中的全部构造器对象
        Constructor[] constructors = c.getDeclaredConstructors();
        //c遍历构造器
        for (Constructor constructor : constructors) {
            System.out.println(constructor.getName() + "====>" + constructor.getParameterCount());

        }
    }

    //3获取单个构造器getConstructor
    @Test
    public void getConstructor() throws Exception {
        //a第一步:获取类对象
        Class c = Student.class;
        //b定位单个构造器(按照参数定位午餐构造器)
        Constructor cons = c.getConstructor();
        System.out.println(cons.getName() + "====>" + cons.getParameterCount());
    }

    //4.getDeclaredConstructor

    @Test
    public void getDeclaredConstructor() throws Exception {
        //a第一步:获取类对象
        Class c = Student.class;
        //b定位单个构造器(按照参数定位午餐构造器)
        Constructor cons = c.getDeclaredConstructor();
        System.out.println(cons.getName() + "====>" + cons.getParameterCount());
       //c定位有参数构造器
        Constructor cons1 = c.getDeclaredConstructor(String.class,int.class);
        System.out.println(cons1.getName() + "====>" + cons1.getParameterCount());
    }

}

 

public class TestStudeng02 {
    @Test
    public void getDeclaredConstructor() throws Exception {
        //1.调用构造器得到一个类的对象返回
        //a第一步:获取类对象
        Class c = Student.class;
        //b定位单个构造器(按照参数定位无参构造器)
        Constructor cons = c.getDeclaredConstructor();
        System.out.println(cons.getName() + "====>" + cons.getParameterCount());

        Student s = (Student) cons.newInstance();  //根据指定的构造器创建对象
        System.out.println(s);

        //c定位有参数构造器
        Constructor cons1 = c.getDeclaredConstructor(String.class,int.class);  //传的是参数类型
        System.out.println(cons1.getName() + "====>" + cons1.getParameterCount());

        Student s1 = (Student) cons1.newInstance("哇哈哈",1000);
        System.out.println(s1);

    }

}

 ④反射获取成员变量对象

 

 

public class FieldDemo1 {
    @Test
    public void getDeclaredFields(){
        //a定位class对象
        Class c = Student.class;
        //b获取所有成员变量
        Field[] fields = c.getDeclaredFields();
        //遍历
        for (Field field : fields) {
            System.out.println(field.getName() + "--->" + field.getType());

        }
    }

    @Test
    public void getDeclaredField() throws Exception {
        //a定位class对象
        Class c = Student.class;
        //b获取某个成员变量
        Field f = c.getDeclaredField("age");
        System.out.println(f.getName() + "-->" + f.getType());

    }


}
public class FieldDemo2 {
    @Test
    public void getDeclaredField() throws Exception {
        //a定位class对象
        Class c = Student.class;
        //b获取某个成员变量
        Field ageF = c.getDeclaredField("age");

        ageF.setAccessible(true);  //暴力打开权限

        //c赋值
        Student s = new Student();
        ageF.set(s,18); //s.setAge(18)
        System.out.println(s);

        //d取值
        int age = (int) ageF.get(s);
        System.out.println(age);


    }
}

 ⑤反射获取方法对象

 

public class Dog {
    private String name;

    public Dog(String name) {
        this.name = name;
    }

    public void run(){
        System.out.println("狗刨的快");
    }

    public void eat(){
        System.out.println("狗吃骨头");
    }

    public String eat(String name){
        System.out.println("狗吃" + name);
        return "吃得很开心";
    }

    public static void inAdd(){
        System.out.println("一群单身狗");
    }

    public Dog() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
public class MethodDemo1 {
    @Test
    public void getDeclareMethods(){
        //a获取类
        Class c = Dog.class;
        //b获取全部方法
        Method[] methods = c.getDeclaredMethods();
        //c遍历
        for (Method method : methods) {
            System.out.println(method.getName() + " 参数个数" + method.getParameterCount());

        }

    }

    @Test
    public void getDeclareMethod() throws Exception {
        //a获取类
        Class c = Dog.class;
        //b获取单个方法
        Method me1 = c.getDeclaredMethod("eat");
        Method me2 = c.getDeclaredMethod("eat",String.class);

        me1.setAccessible(true);
        me2.setAccessible(true);

        //c出发方法的执行
        Dog d = new Dog();
        //注意:方法如果没有返回值,那么返回的是null
        Object resault = me1.invoke(d);
        System.out.println(resault);

        Object resault2 = me2.invoke(d,"骨头");
        System.out.println(resault2);

    }


}

⑥反射的作用--绕过编译阶段为集合添加数据

 

public class ReflectDemo {
    public static void main(String[] args) throws Exception {
        //需求:反射实现泛型擦除后,加入其他类型的元素
        ArrayList<String> list1 = new ArrayList<>();
        ArrayList<Integer> list2 = new ArrayList<>();

        System.out.println(list1.getClass());
        System.out.println(list2.getClass());

        System.out.println(list1.getClass() == list2.getClass());  //Arraylist.class
        System.out.println("--------------------------");
        ArrayList<Integer> list3 = new ArrayList<>();
        list3.add(11);
        list3.add(12);

        Class c = list3.getClass(); //Arrraylist.class ==> public booolean add(E e)
        Method add = c.getDeclaredMethod("add", Object.class);
        boolean rs = (boolean) add.invoke(list3,"哇哈哈");
        System.out.println(rs);
        System.out.println(list3);
    }
}

⑦反射的作用--通用框架的底层原理

 

public class MybatiesUtiles {
    /**
     * 保存任意类型的对象
     * @param obj
     */
    public static void save(Object obj){

        try (PrintStream ps = new PrintStream(new FileOutputStream("junit-reflect-annnotation-proxy-app\\src\\data.txt",true));){

            //1.提取这个对象的全部成员变量,只有反射可以解决
            Class c = obj.getClass();
            ps.println("============"+ c.getSimpleName() + "==============");

            //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();
        }

    }
}
public class ReflectDemo {
    public static void main(String[] args) {
        Student s = new Student("哇哈哈",'女',19);
        MybatiesUtiles.save(s);

        Teacher t = new Teacher("朱老大三",33,100000);
        MybatiesUtiles.save(t);

    }
}

 3️⃣注解

 

public @interface NyBook {
    String name();
    String[] authors();
    double price();
}

 

 

 

@Target({ElementType.METHOD,ElementType.FIELD})  //元注解
@Retention(RetentionPolicy.RUNTIME)  //一直活着  在运行阶段也不消失
public @interface MyTest {
}

4️⃣动态代理

 

public class StarAgentProxy {
    /**
      设计一个方法来返回一个明星对象的代理对象
     */
    public static Skill getProxy(Star obj ){
        //为杨超越生成一个代理对象
        /**
         * public static Object newProxyInstance(ClassLoader loader,  类加载器
         *                            Class<?>[] interfaces,  对象实现的接口列表
         *                             InvocationHandler h)
         */
        return (Skill) Proxy.newProxyInstance(obj.getClass().getClassLoader(),
                obj.getClass().getInterfaces(), new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("收到首付款");
                        //真正的让杨超月去唱歌跳舞
                        //method正在调用的方法对象 args代表这个方法的参数
                        Object rs = method.invoke(obj,args);
                        System.out.println("尾款收到");
                        return rs;
                    }
                });

    }
}
public class Test {
    public static void main(String[] args) {
        //目标:理解动态代理的执行流程,学习并开发一个代理对象出来
        //1创建一个对象,对象的类必须实现接口
        Star s = new Star("杨超越");
        //为杨超越对象生成一个代理对象(经纪人)
        Skill s2 = StarAgentProxy.getProxy(s);
        s2.jump();
        s2.sing();


    }
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值