【Java】单元测试、反射、注解

1 单元测试(白盒测试)

  • 测试类

  • 独立运行(返回值void 、参数void)

  • 方法添加@Test

  • 被测试的类

package com.xhh.calc.calcClass;

/**
 * @author : xhh
 * @email : xhh0608@foxmail.com
 * @date : 2021.10.4
 */
public class Calc {
    public int addNum(int a, int b){
        return a + b;
    }
    public int subNum(int a, int b){
        return a - b;
    }
}
  • 测试类
package com.xhh.calc.test;

import com.xhh.calc.calcClass.Calc;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
/**
 * @author : xhh
 * @email : xhh0608@foxmail.com
 * @date : void
 */
public class CalcTest {
    @Before
    public void init(){
        System.out.println("init  申请资源,如IO等等");
    }
    @After
    public void close(){
        System.out.println("close ..  释放资源");
    }

    @Test
    public void testAdd(){
        Calc calc = new Calc();
        int ret = calc.addNum(1, 2);
        Assert.assertEquals(ret, 3);
    }

    @Test
    public void testSub(){
        Calc calc = new Calc();
        // 断言
        int ret = calc.subNum(1, 2);
        Assert.assertEquals(ret, -1);
    }
}

/**
 init  申请资源,如IO等等
 close ..  释放资源
 init  申请资源,如IO等等
 close ..  释放资源
 */

2 反射

类对象

  • 成员变量:Field[] fields
  • 构造方法:Constructor[] cons
  • 成员方法:Method[] methods
2.1 获取Class对象的方式

在这里插入图片描述

// [1] 源码阶段
Class.forName("类名");

// [2] 类对象阶段
类名.class

// [3] 通过对象
对象.getClass()
package com.xhh.reflection;

import com.xhh.reflection.domain.Person;

/**
 * @author : xhh
 * @email : xhh0608@foxmail.com
 * @date : void
 */
public class GetClass {
    public static void main(String[] args) throws Exception {
        // [1] 源码阶段
        Class<?> cls1 = Class.forName("com.xhh.reflection.domain.Person");
        System.out.println(cls1);

        // [2] 类对象阶段
        Class<Person> cls2 = Person.class;

        // [3] 通过对象
        Person xhh = new Person("xhh", 18);
        Class<? extends Person> cls3 = xhh.getClass();

        System.out.println(cls1 == cls2); // true
        System.out.println(cls1 == cls3); // true
    }
}
2.2 使用Class

在这里插入图片描述

  • Person
package com.xhh.reflection.domain;

public class Person {

    public Person(){}
    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }
    public void methodInfo(){
        System.out.println("methodInfo ...");
    }
    private String name;
    private Integer age;

    public String info = "xhh123456";
}
package com.xhh.reflection;

import com.xhh.reflection.domain.Person;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class GetClass {
    public static void main(String[] args) throws Exception {
        // 源码阶段
        Class<?> cls1 = Class.forName("com.xhh.reflection.domain.Person");
        System.out.println(cls1);

        // [*]获取构造器
        // Person()
        Constructor<?> cons1 = cls1.getConstructor();
        // Person(String name, Integer age)
        Constructor<?> cons2 = cls1.getConstructor(String.class, Integer.class);
        // 创建对象
        Person mcy = (Person)cons2.newInstance("mcy", 123);
        System.out.println(mcy);

        // [*]获取方法
        Method methodInfo = cls1.getMethod("methodInfo");
        // 执行方法
        methodInfo.invoke(mcy);


        // [*]获取(public)成员变量   设置值和得到值
        Field info = cls1.getField("info");
        info.setAccessible(true); // 暴力反射  可以访问所以权限类型

        info.set(mcy, "mcy----newValue"); // set
        Object o = info.get(mcy);         // get
        System.out.println(o);
    }
}
2.3 案例
  • Cat
package com.xhh.reflection;
public class Cat {
    public void catMethod(){
        System.out.println("miao miao miao ...");
    }
}
  • Dog
package com.xhh.reflection;
public class Dog {
    public void dogMethod(){
        System.out.println("wang wang wang ...");
    }
}
  • pro.properties
#className=com.xhh.reflection.Cat

className=com.xhh.reflection.Dog
methodName=dogMethod
  • Main
package com.xhh.reflection;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.util.Properties;

public class TestPro {
    public static void main(String[] args) throws Exception {
        // [1] 配置文件
        Properties properties = new Properties();
        properties.load(new FileInputStream("./src/pro.properties"));

        String className = properties.getProperty("className");
        String methodName = properties.getProperty("methodName");

        // [2] 加载字节码类
        Class<?> cls = Class.forName(className);
        Object obj = cls.newInstance();
        Method method = cls.getMethod(methodName);

        // [3] 执行方法
        method.invoke(obj);
    }
}

3 注解

3.1 内置三种注解
package com.xhh.reflection;

// [3] 压制所有警告
@SuppressWarnings("all")
public class Annotation_ {

    // [1] 重写父类方法
    @Override
    public String toString(){
        return super.toString();
    }

    // [2] 标记过时 不推荐使用
    @Deprecated
    public void showVersion1(){
        // 过时
    }
    public void showVersion2(){
        // 新方法
    }
}
3.2 自定义注解
  • 格式
public @interface XhhAnno{
}
  • 元注解
    在这里插入图片描述
package com.xhh.reflection;

import java.lang.annotation.*;

/**
 * @author : xhh
 * @email : xhh0608@foxmail.com
 * @date : void
 */

@Target(value = {ElementType.TYPE, ElementType.METHOD}) // 作用于类和方法
@Retention(RetentionPolicy.RUNTIME) // 运行时(自定义一般用这个)
@Documented // 注释可以被抽取到Doc文档中
@Inherited  // 自动可以被子类继承
public @interface Anno_ {
}
  • 案例(加载配置文件)

注解

package com.xhh.reflection;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

// 作用于类 保留至运行时
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface LoadPro {
    String className();
    String methodName();
}

使用

package com.xhh.reflection;

import java.lang.reflect.Method;

@LoadPro(className = "com.xhh.reflection.Dog", methodName = "dogMethod")
public class LoadProTest {
    public static void main(String[] args) throws Exception {
        // 1 解析注解
        // 1.1 获取当前类的字节码对象
        Class<LoadProTest> lpcls = LoadProTest.class;
        // 1.2 获取定义注解的对象
        LoadPro anno = lpcls.getAnnotation(LoadPro.class);
        // 1.3 通过注解对象的抽象方法,获取返回值
        String className = anno.className();
        String methodName = anno.methodName();

        // 反射对象执行方法
        Class<?> cls = Class.forName(className);
        Object obj = cls.newInstance();
        Method method = cls.getMethod(methodName);
        method.invoke(obj);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值