junit、javabean和注解

junit框架的使用


操作步骤:

  1. 导入junit框架 (已经集成了 junit 工具)
  2. 项目文件右键 build path 选项 add Libraries ,添加 junit 框架
  • Junit 4.x Java5 以后的版本
  • Junit 5.x Java8 以后的版本

只要符合 junit 规范,直接在一个方法上点击右键运行

规范:测试类建议使用 XxxTest. 以 Test 结尾,千万不要自己创建一个 Test 类,定义符合规范的测试方法,方法必须公共、无参数、无返回,方法名使用 Test 开头,在要测试的方法上面添加 @Test

注意:全部 @Test 方法都规范,才能测试

面向接口编程


  1. 根据业务先写接口并且用文档注释将方法的功能、参数、返回值都写清楚
  2. 写一个实现类实现接口,先不写实现
  3. 用 junit 生成测试类,再实现类上右键 new 一个 junit test case
  4. 写完一个方法就测试一个方法。

先完成测试类,再写实现,写一个,测一个,频繁总结

一定要养成一个 规范的 junit 测试

一个规范的 junit 测试,会有3个类, 接口定义规范, 实现类有具体实现, 测试类是方法入口,

javabean


规范:

  1. 使用 public 修饰
  2. 字段私有化
  3. 提供 get/set 方法
  4. 公共的无参数的构造器,(使用反射,使用字节码对象去创建对象)

三大成员:

事件、方法、属性

属性不是字段,属性是通过 get/set 方法推导来的,例如

1
2
3
4
5
6
7
8
// 属性为 name
public String getName() {
return name;
}
// 属性为 startIndex
public int getStartIndex() {
return (currentPage - 1) * pageSize;
}

字段是 boolean 的,读方法不是 get 开头,是 is 开头

内省(Introspector)


内省,操作内省的入口类。

作用:获取到属性名和属性类型,获取属性对应的读写方法作属性值

常用API:

  1. 通过字节码对象,获取到 javabean 的描述对象
    返回javabean 的描述对象 Introspector 类
    public static BeanInfo getBeanInfo(Class beanClass, Class stopClass)

  2. 通过 javabean 描述对象获取属性描述器 BeanInfo 类
    获取属性描述器
    PropertyDescriptor[] getPropertyDescriptors()

  3. 通过属性描述器,获取到属性名,属性类型,读写方法
    PropertyDescriptor 类,
    public String getName() // 获取属性名
    public Class<?> getPropertyType() // 获取属性类型
    public Method getReadMethod() // 获取读方法
    public Method getWriteMethod() // 获取写方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public void testIntrospector() throws Exception {
// 1. 通过字节码对象获取 javabean 描述,
// 从Linkman 到 Object ,不然会一直把所有父类的 beanInfo 拿到
BeanInfo info = Introspector.getBeanInfo(Linkman.class, Object.class);
Object obj = Linkman.class.newInstance();
// 2. 通过描述对象获取属性相关的信息
PropertyDescriptor[] pds = info.getPropertyDescriptors();
for (PropertyDescriptor pd : pds) {
// 每个 pd 对象,就是一个属性的描述对象
System.out.println(pd.getName()); // 属性名
System.out.println(pd.getPropertyType()); // 属性值类型
System.out.println(pd.getReadMethod()); // 读取方法
System.out.println(pd.getWriteMethod()); // 写方法

String name = pd.getName();
Method m = pd.getWriteMethod();
if ("name".equals(name)) {
m.invoke(obj, "李朝");
} else if ("age".equals(name)) {
m.invoke(obj, "18");
}
}
System.out.println(obj);
}

javabean 与 map 之间的转换


需求分析,将需求变为可执行的步骤,写出每个步骤的关键代码,注意概念转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class Bean2MapDemo {
@Test
public void testBean2Map() throws Exception {
Linkman man = new Linkman("1", "李朝", "18", "广州", "java", "lacuself@126.com");
Map<String, Object> map = Bean2MapDemo.bean2Map(man);

Object obj = Bean2MapDemo.map2bean(map, man.getClass());
System.out.println(obj);
}

public static Map<String, Object> bean2Map(Object obj) throws Exception {
// 获取 beaninfo
BeanInfo info = Introspector.getBeanInfo(obj.getClass(), Object.class);
PropertyDescriptor[] pds = info.getPropertyDescriptors();
Map<String, Object> map = new HashMap<String, Object>();
for (PropertyDescriptor pd : pds) {
Method m = pd.getReadMethod();
map.put(pd.getName(), m.invoke(obj));
}
return map;
}

public static Object map2bean(Map<String, Object> map, Class cls) throws Exception {
BeanInfo info = Introspector.getBeanInfo(cls, Object.class);
PropertyDescriptor[] pds = info.getPropertyDescriptors();
Object obj = cls.newInstance();
for (PropertyDescriptor pd : pds) {
Object value = map.get(pd.getName());
Method m = pd.getWriteMethod();
m.invoke(obj, value);
}
return obj;
}
}

注解


功能:简化代码,类似于自定义代码块

Annotation

@interface + 注解名

1
2
3
4
5
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {

}

格式:@注解名(属性名=属性值,属性名=属性值)

注解贴在程序元素上,想要拥有某一些功能,

  1. 注解本身
  2. 被贴的程序元素
  3. 三方程序,使用反射给注解赋予功能(注解背后,一定有一段代码给注解赋予功能)

元注解


注解用来描述程序元素,元注解用来描述注解

注解:用来贴在 类/方法/变量等之上的一个标记,第三方程序可以通过这个标记赋予一定功能。

注解的原理,使用简单,但是在注解的背后一定有一堆的实现功能的反射的代码。

元注解:在定义注解的时候用来贴在注解上的注解,用来限定注解的用法。

@Target


表示注解可以贴在哪些位置(类,方法,构造器等等),位置的常量封装在 ElementType 枚举类中:

1
2
3
4
5
6
7
8
ElementType.ANNOTATION_TYPE // 只能修饰 Annotation
ElementType.CONSTRUCTOR // 只能 修饰构造方法
ElementType.FIELD // 只能修饰字段
ElementType.LOCAL_VARIABLE // 只能修饰局部变量
ElementType.METHOD // 只能修饰方法
ElementType.PACKAGE // 只能修饰包(极少使用)
ElementType.PARAMETER // 只能修饰参数
ElementType.TYPE // 只能修饰类,接口,枚举

@Retention


表示注解可以保存在哪一个时期,表示时期的值,封装在 RetentionPolicy 枚举类中:

  • SOURCE:注解只能存在于源文件中,编译之后,字节码文件中没有(辅助编译)
  • CLASS:注解可以存在于源文件和字节码文件中,一旦加载进 JVM,在 JVM 中不存在
  • RUNTIME:注解可以存在于源文件,字节码文件,JVM 中(程序运行过程中都存在)

注意:自定义的注解,使用RUNTIME(使用反射赋予注解功能)

使用 @Documented 标注的标签会保存到 API 文档中

@Inherited 标注的标签可以被子类所继承

注解的语法


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Target(ElementType.TYPE) // 表示注解可以贴在哪些位置上
@Retention(RetentionPolicy.RUNTIME)
public @interface VIP {
// 1. 注解中,也是抽象方法,不能有方法体
// 2. 注解中,方法叫属性名,返回的值是属性值类型
// 3. 给属性设置默认值 default
// 4. 如果需要要写的属性只有一个,且属性名叫做 value ,可以省略属性名
// 5. 属性值的类型只能是基本类型、String、Class、Annotation、枚举以及一维数组。
// 6. 数组,如果值只有一个,可以用{}。也可以不用,如果值有多个,一定要用{}

String name() default "你好";
int age();
String[] hobby();
}

@VIP(name = "李朝",age = 18, hobby = {"ss", "bb"})
public class Linkman {

lombok 插件


安装插件

1
java -jar /Users/Ammar/Desktop/java/大神班资料/jars/lombok.jar

执行命令行

文章作者: Ammar
文章链接: http://lizhaoloveit.cn/2019/06/30/junit%E3%80%81javabean%E5%92%8C%E6%B3%A8%E8%A7%A3/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Ammar's Blog
打赏
  • 微信
  • 支付宝

评论