Java高级编程
本文摘要: 单元测试部分介绍了Junit框架的优势和使用方法,包括测试方法编写规范、断言机制和常用注解,相比传统main方法测试更高效规范。 反射部分详细讲解了获取Class对象的三种方式(类名.class/Class.forName/对象.getClass),以及通过反射获取构造器、成员变量和方法的操作: 构造器:获取Constructor对象并初始化实例 成员变量:Field对象进行取值赋值操
文章目录
一、单元测试
概念:就是针对最小的功能单元(方法),编写测试代码对其进行正确性测试
1.1 之前测试方法
①只能在main方法中编写测试代码,去调用其他方法进行测试
②无法实现自动化测试,一个方法测试失败,可能影响其他方法的测试
③无法的到测试的报告,需要程序员自己去观察测试是否成功
1.2 Junit单元测试框架
概念:可以用来对方法进行测试,他是第三方公司开源出来的
优点:①可以灵活的编写测试代码,可以针对某个方法执行测试,也支持一键完成对全部方法的自动化测试,且各自独立②不需要程序员去分析测试的结果,会自动生成测试报告出来
需求:某个系统,有多个业务方法,请使用Junit单元测试框架,编写测试代码,完成对这些方法的正确性测试
具体步骤:①将Junit框架的jar包导入到项目中(注意IDEA已经集成了Junit框架,我们不需要自己手工导入)②为需要测试的业务类,定义对应的测试类,并为每个业务方法,编写对应的测试方法(必须:公共、无参、无返回值)③测试方法上必须声明Test注解,然后在测试方法中,缩写代码调用背测试的业务方法进行测试④开始测试:选中测试方法,右键选择Junit运行,如果测试通过,测试绿色,测试失败,则是红色
public static int index(String data) {
if (data == null){
return -1;
}
return data.length() - 1;
}
@Test
public void testGetMxaIndex() {
int i1 = Test01.index(null);
// 断言
Assert.assertEquals("测试失败", -1, i1);
int i2 = Test01.index("");
Assert.assertEquals("测试失败", -1, i2);
int i3 = Test01.index("admin");
Assert.assertEquals("测试失败", 4, i3);
}
1.3 Junit常用注解


二、反射
反射就是:加载类,并允许以编程的方式解剖类中的各种成分(成员变量、方法、构造器等)①反射第一步,加载类,获取类的字节码:Class对象②获取类的构造器:Constructor对象③获取类的成员变量:Field对象④获取类的成员方法:Method对象
2.1 获取Class对象的三种方式
第一种:Class c1 = 类名.class
第二种:调用Class提供方法:public static Class forName(String package);
第三种:Object提供的方法:public Class getClass(); Class c3 = 对象.getClass();
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private Integer id;
private String name;
private String surname;
private String email;
private String phone;
private String address;
}
public class Test01Class {
public static void main(String[] args) throws Exception {
// 方式一:
Class c1 = Student.class;
System.out.println(c1);
// 方式二:
Class<?> c2 = Class.forName("com.chenxd.reflect.Student");
System.out.println(c2);
// 方式三:
Student s = new Student();
Class c3 = s.getClass();
System.out.println(c3);
}
}
2.2 获取构造器对象

@Test
public void testConstuctors() throws Exception {
Class c = Cat.class;
// 获取全部构造器
Constructor[] constructor = c.getDeclaredConstructors();
for (Constructor constructor1 : constructor) {
System.out.println(constructor1.getName()+"========"+constructor1.getParameterCount());
}
}
@Test
public void testConstuctors2() throws Exception {
Class c = Cat.class;
// 获取单个构造器
// 定位无参构造器
Constructor c1 = c.getDeclaredConstructor();
System.out.println(c1);
Constructor c2 = c.getDeclaredConstructor(int.class, String.class, int.class);
System.out.println(c2);
}
获取构造器的作用:初始化对象返回
@Test
public void testConstuctors2() throws Exception {
Class c = Cat.class;
// 获取单个构造器
// 定位无参构造器
Constructor c1 = c.getDeclaredConstructor();
System.out.println(c1);
Constructor c2 = c.getDeclaredConstructor(int.class, String.class, int.class);
System.out.println(c2);
// 得到构造器,依然是初始化对象
Cat cat1 = (Cat)c1.newInstance();
System.out.println(cat1);
// 禁止检查反射权限:否则私有的反射不了
c2.setAccessible(true);
Cat cat2 = (Cat)c2.newInstance(1,"kk",30);
System.out.println(cat2);
}
2.3 获取成员变量

赋值取值方法
@Test
public void testGetFields() throws Exception {
Class cat = Cat.class;
Field[] declaredFields = cat.getDeclaredFields();
// 获取所有成员变量
for (Field declaredField : declaredFields) {
System.out.println(declaredField.getType() + "=======" + declaredField.getName());
}
// 获取某个成员变量
Field name = cat.getDeclaredField("name");
// 成员变量的作用就是取值赋值
Cat c = new Cat();
name.setAccessible(true);
name.set(c, "kkkkk");
String c2 = (String) name.get(c);
System.out.println(c2);
}
2.4 获取成员方法


@Test
public void TestGetMethod() throws Exception {
Class c = Cat.class;
// 获取所有方法
Method[] method = c.getDeclaredMethods();
for(Method m : method){
System.out.println(m.getName()+":"+m.getParameterCount());
}
// 获取单个
Method run = c.getDeclaredMethod("run", String.class);
// 调用
Cat cat = new Cat();
Object result = run.invoke(cat,"kjkk");
System.out.println(result);
}
2.5 反射的作用
①基本作用:可以的到一个类的全部成分然后操作②可以破坏封装性③最重要的作用:适合做Java的框架,基本上,主流的框架都会基于反射设计出一些通用的功能
三、注解(Annotation)
就是Java代码里的特殊标记,比如@Test,作用是:让其他程序根据注解信息来决定怎么执行该程序
注意:注解可以用在类上、构造器上、方法上、成员变量上、参数上、等位置处
3.1 自定义注解
public @intercace 注解名称 {
public 属性类型 属性名() default 默认值;
}
特殊属性:value如果注解中只有一个value属性,使用注解时,value名称可以不用写
public @interface MyTest {
public String value();
public String name() default "张三";
public int age() default 18;
}
@MyTest(value = "9", name = "李四",age = 90)
public class Test01 {
@MyTest(value = "9", name = "李四",age = 90)
private int m;
@MyTest(value = "9", name = "李四",age = 90)
public static void main(String[] args) {
}
}
3.2 注解的原理
①注解本质就是一个接口,java中所有注解都是继承了Annotation接口的
②@注解(……)其实就是一个实现类对象,实现了该注解以及Annotation接口
3.3 元注解
指的是:修饰注解的注解


3.4 注解的解析
就是判断类上、方法上、成员变量上是否存在注解,并把注解里的内容给解析出来
指导思想:要解析谁上面的注解就应该先拿到谁,比如要解析类上面的注解,则应该先获取该类的Class对象,再通过Class对象解析其上面的注解,Class、Method、Field、Constructor、都实现了AnnotatedElement接口,它们都拥有注解解析的能力
更多推荐


所有评论(0)