一、单元测试
就是针对最小的功能单元(方法),编写测试代码对其进行正确性测试。
1.1 Junit单元测试框架
可以用来对方法进行测试,它是由Junit公司开源出来的 优点 可以灵活的编写测试代码,可以针对某个方法执行测试,也支持一键完成对全部方法的自动化测试,且各自独立。 不需要程序员去分析测试的结果,会自动生成测试报告出来。 1、Junit单元测试是做什么的? 测试类中方法的正确性的 2、JUnit单元测试的实现过程是什么样的? 必须导入Junit框架的jar包 定义的测试方法必须是无参数无返回值,且公开的方法 测试方法使用@Test注解标记 3、JUnit测试某个方法,测试全部方法怎么处理?成功的标志是什么? 测试某个方法直接右键该方法启动测试 测试全部方法,可以选择类或者模块启动 红色失败,黄色警告,绿色通过需求
某个系统,有多个业务方法,请使用Junit单元测试框架,编写测试代码,完成对这些方法的正确性测试。
具体步骤
①将Junit框架的jar包导入到项目中(资料中已经提供)
②为需要测试的业务类,定义对应的测试类,并为每个业务方法,编写对应的测试方法(必须:公共、无参、无返回值)
③测试方法上必须声明@Test注解,然后在测试方法中,编写代码调用被测试的业务方法进行测试;
④开始测试:选中测试方法,右键选择“JUnit运行” ,如果测试通过则是绿色;如果测试失败,则是红色
public class StringUtil {
//获取字符串长度
public static void printNumber(String name) {
System.out.println("名字长度:" + name.length());
}
}
public class StringUtilTest {
@Test
public void testprintNumber(){
//printNumber为静态方法, 直接用类StringUtil调用
StringUtil.printNumber("hello");
StringUtil.printNumber("123");
StringUtil.printNumber("");
StringUtil.printNumber(null);//异常:java.lang.NullPointerException空指针异常
}
}
1.1.1 断言
public class StringUtil {
//获取字符串的最大索引
public int getMaxIndex(String data) {
if (data == null) {
return -1;
}
return data.length();
}
}
public class StringUtilTest {
@Test
public void testGetMaxIndex(){
//创建对象
StringUtil stringUtil = new StringUtil();
//调用方法
int index1 = stringUtil.getMaxIndex("hello");
Assert.assertEquals("最大索引不符合预期",4, index1);//断言:会影响后面的程序执行
int index2 = stringUtil.getMaxIndex("123");
Assert.assertEquals("最大索引不符合预期",3, index2);//预期相同,打印台不会有东西输出
int index3 = stringUtil.getMaxIndex("李四");
int index4 = stringUtil.getMaxIndex("");
int index5 = stringUtil.getMaxIndex(null);
}
}
1.2 Junit框架的常见注解
Junit 4.xxxx版本
注解 | 说明 |
---|---|
@Test | 测试类中的方法必须用它修饰才能成为测试方法,才能启动执行 |
@Before | 用来修饰一个实例方法,该方法会在每一个测试方法执行之前执行一次。 |
@After | 用来修饰一个实例方法,该方法会在每一个测试方法执行之后执行一次。 |
@BeforeClass | 用来修饰一个静态方法,该方法会在所有测试方法之前只执行一次。 |
@AfterClass | 用来修饰一个静态方法,该方法会在所有测试方法之后只执行一次。 |
在测试方法执行前执行的方法,常用于:初始化资源。
在测试方法执行完后再执行的方法,常用于:释放资源。
/**
* 测试类的初始化代码
* 每个测试执行开始前,调用
*/
@Before
public void init(){
System.out.println("调用init方法");
}
/**
* 每个测试执行结束时调用
*/
@After
public void end(){
System.out.println("测试方法执行结束");
}
/**
* 测试类的初始化代码
* 在所有测试方法之前只执行一次。
*/
@BeforeClass
public static void BeforeClass(){
System.out.println("调用BeforeClass方法");
}
/**
* 在所有测试方法之后前只执行一次。
*/
@AfterClass
public static void AfterClass(){
System.out.println("AfterClass测试方法执行结束");
}
Junit 5.xxxx版本
注解 | 说明 |
---|---|
@Test | 测试类中的方法必须用它修饰才能成为测试方法,才能启动执行 |
@BeforeEach | 用来修饰一个实例方法,该方法会在每一个测试方法执行之前执行一次。 |
@AfterEach | 用来修饰一个实例方法,该方法会在每一个测试方法执行之后执行一次。 |
@BeforeAll | 用来修饰一个静态方法,该方法会在所有测试方法之前只执行一次。 |
@AfterAll | 用来修饰一个静态方法,该方法会在所有测试方法之后只执行一次。 |
开始执行的方法:初始化资源
执行完之后的方法:释放资源
二、反射
反射就 加载类,并允许以编程的方式解剖类中的各种成分(成员变量、方法、构造器等)
定义一个Cat类用于下面的测试
public class Cat {
public static int a;
public static final String COUNTRY = "中国";
private String name;
private int age;
public Cat(){
System.out.println("无参数构造器执行了~~");
}
public Cat(String name) {
this.name = name;
}
private Cat(String name, int age) {
System.out.println("有参数构造器执行了~~");
this.name = name;
this.age = age;
}
private void run(){
System.out.println("🐱跑的贼快~~");
}
public void eat(){
System.out.println("🐱爱吃猫粮~");
}
private String eat(String name){
return "🐱最爱吃:" + name;
}
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;
}
@Override
public String toString() {
return "Cat{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
2.1 获取类
反射的第一步是什么 获取Class类对象,如此才可以解析类的全部成分 获取Class对象的三种方式 1. 直接使用类名.class获取:Class c1 = 类名.class 2. 调用Class提供的方法:Class c2 = Class.forName("全类名":包名+类名) 3. 调用Object提供的方法:Class c3 = 对象.getClass()
public class Demo1 {
public static void main(String[] args) throws ClassNotFoundException {
// 1. 直接使用类名.class获取:Class c1 = 类名.class
Class<Cat> c1 = Cat.class;
System.out.println(c1);//class com.wt.b_反射.Cat
// 2. 调用Class提供的方法:Class c2 = Class.forName("全类名")
Class<?> c2 = Class.forName("com.wt.b_反射.Cat");
System.out.println(c2);//class com.wt.b_反射.Cat
// 3. 调用Object提供的方法:Class c3 = 对象.getClass()
Cat cat = new Cat();
Class<? extends Cat> c3 = cat.getClass();// 获取对象的运行类型
System.out.println(c3);//class com.wt.b_反射.Cat
System.out.println("==============");
System.out.println(c3.getName());//com.wt.b_反射.Cat
System.out.println(c3.getSimpleName());//Cat
System.out.println(c3.getPackage().getName());//com.wt.b_反射
System.out.println(c3.getSuperclass());//class java.lang.Object
}
}
2.2 获取构造器
Class提供了从类中获取构造器的方法
方法 | 说明 |
---|---|
Constructor<?>[] getConstructors() | 获取所有的公共构造器(只能获取public修饰的) |
Constructor<?>[] getDeclaredConstructors() | 获取全部构造器(只要存在就能拿到) |
Constructor<T> getConstructor(Class<?>... parameterTypes) | 获取某个公共构造器(只能获取public修饰的) |
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) | 获取某个构造器(只要存在就能拿到) |
获取类构造器的作用:依然是初始化对象返回
Constructor提供的方法 | 说明 |
---|---|
T newInstance(Object... initArgs) | 调用此构造器对象表示的构造器,并传入参数,完成对象的初始化并返回 |
public void setAccessible(boolean flag) | 设置为true,表示禁止检查访问控制(暴力反射) |
获取构造器[下面是Class的方法] Constructor<?>[] getConstructors() 获取所有的公共构造器(只能获取public修饰的) Constructor<?>[] getDeclaredConstructors() 获取全部构造器(只要存在就能拿到) Constructor<T> getConstructor(Class<?>... parameterTypes) 获取某个公共构造器(只能获取public修饰的) Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 获取某个构造器(只要存在就能拿到) 使用构造器(创建对象)[下面是Constructor的方法] T newInstance(Object... initArgs) 调用此构造器对象表示的构造器,并传入参数,完成对象的初始化并返回 public void setAccessible(boolean flag) 设置为true,表示禁止检查访问控制(暴力反射) 注意 使如果想使用private修饰构造器反射创建对象,需要暴力反射(禁止JVM检查构造方法的访问权限)
public class Demo2 {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
//1.获取类class对象
Class<Cat> catClass = Cat.class;
// Constructor<?>[] getConstructors() 获取所有的公共构造器(只能获取public修饰的)
Constructor<?>[] constructors = catClass.getConstructors();
int length = constructors.length;
System.out.println("公共的构造器个数:" + length);//1(只有一个公共的构造器)
System.out.println("===============");
// Constructor<?>[] getDeclaredConstructors() 获取全部构造器(只要存在就能拿到)
Constructor<?>[] declaredConstructors = catClass.getDeclaredConstructors();
System.out.println("全部构造器个数:" +declaredConstructors.length);
for (Constructor<?> declaredConstructor : declaredConstructors) {
System.out.println("构造器参数名字:"+declaredConstructor.getName());//Cat()
System.out.println("构造器参数个数:"+declaredConstructor.getParameterCount());
}
System.out.println("===============");
// Constructor<T> getConstructor(Class<?>... parameterTypes) 获取某个公共构造器(只能获取public修饰的)
Constructor<Cat> constructor = catClass.getConstructor();
System.out.println("公共构造器为:"+constructor);//公共构造器为:public com.wt.b_反射.Cat()
Constructor<Cat> constructor1 = catClass.getConstructor(String.class);
System.out.println("构造器为:"+constructor1);//构造器为:public com.wt.b_反射.Cat(java.lang.String)
System.out.println("===============");
// Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 获取某个构造器(只要存在就能拿到)
Constructor<Cat> declaredConstructor = catClass.getDeclaredConstructor(String.class, int.class);
System.out.println("构造器为:"+declaredConstructor);//构造器为:private com.wt.b_反射.Cat(java.lang.String,int)
System.out.println("构造器的参数个数为:"+declaredConstructor.getParameterCount());//构造器的参数个数为:2
System.out.println("===================");
//创建Cat对象,使用构造器对象,公共无参
Constructor<Cat> constructor3 = catClass.getConstructor();
Cat cat1 = constructor3.newInstance();
System.out.println(cat1);//Cat{name='null', age=0}
System.out.println("===================");
//创建Cat对象,使用构造器对象,私有有参
//IllegalAccessException:访问控制异常,因为反射创建对象时,默认是禁止访问控制,所以需要使用暴力反射
Constructor<Cat> declaredConstructor2 = catClass.getDeclaredConstructor(String.class, int.class);
declaredConstructor2.setAccessible(true);
Cat cat2 = declaredConstructor2.newInstance("小花", 2);
System.out.println(cat2);//Cat{name='小花', age=2}
}
}
2.3 获取成员变量
Class提供了从类中获取成员变量的方法
方法 | 说明 |
---|---|
public Field[] getFields() | 获取类的所有公共成员变量(只能获取public修饰的) |
public Field[] getDeclaredFields() | 获取类的全部成员变量(只要存在就能拿到) |
public Field getField(String name) | 获取类的某个公共成员变量(只能获取public修饰的) |
public Field getDeclaredField(String name) | 获取类的某个成员变量(只要存在就能拿到) |
获取到成员变量的作用:依然是赋值、取值
Field的方法 | 说明 |
---|---|
public void set(Object obj, Object value) | 赋值 |
public Object get(Object obj) | 取值 |
public void setAccessible(boolean flag) | 设置为true,表示禁止检查访问控制(暴力反射) |
获取成员变量[Class提供] public Field[] getFields() 获取类的所有公共成员变量(只能获取public修饰的) public Field[] getDeclaredFields() 获取类的全部成员变量(只要存在就能拿到) public Field getField(String name) 获取类的某个公共成员变量(只能获取public修饰的) public Field getDeclaredField(String name) 获取类的某个成员变量(只要存在就能拿到) 使用成员变量(赋值和取值) [Field提供] public void set(Object obj, Object value): 赋值 public Object get(Object obj): 取值 public void setAccessible(boolean flag): 设置为true,表示禁止检查访问控制(暴力反射) 注意 使如果想使用private修饰的变量,需要暴力反射
public class Demo3 {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
//1.获取类class对象
Class<Cat> catClass = Cat.class;
// public Field[] getFields() 获取类的所有公共成员变量(只能获取public修饰的)
Field[] fields = catClass.getFields();
System.out.println("公共成员变量个数:"+fields.length);//公共成员变量个数:2
for (Field field : fields) {
System.out.println("成员变量"+field);
System.out.println("成员变量类型:"+field.getType());
System.out.println("成员变量名:"+field.getName());
System.out.println("===================");
}
System.out.println();
// public Field[] getDeclaredFields() 获取类的全部成员变量(只要存在就能拿到)
Field[] declaredFields = catClass.getDeclaredFields();
System.out.println("全部成员变量个数:"+declaredFields.length);//全部成员变量个数:4
for (Field declaredField : declaredFields) {
System.out.println("成员变量:"+declaredField);
System.out.println("成员变量类型:"+declaredField.getType());
System.out.println("成员变量名:"+declaredField.getName());
System.out.println("===================");
}
System.out.println();
// public Field getDeclaredField(String name) 获取类的某个成员变量(只要存在就能拿到)
Field aField = catClass.getDeclaredField("a");
System.out.println("aField:"+aField.getName() + " " + aField.getType());//aField:a int
Field nameField = catClass.getDeclaredField("name");
System.out.println("nameField:"+nameField.getName() + " " + nameField.getType());//nameField:name class java.lang.String
Field counField = catClass.getDeclaredField("COUNTRY");
System.out.println("counField:"+counField.getName() + " " + counField.getType());//counField:COUNTRY class java.lang.String
System.out.println("===================");
// 使用成员变量(赋值和取值) [Field提供]
//1.1 创建对象
Cat cat = new Cat();
int a = (int)aField.get(cat);
System.out.println("a的值为:"+a);//a的值为:0
aField.set(cat,100);
int a1 = (int)aField.get(cat);
System.out.println("a1的值为:"+a1);//a1的值为:100
String country = (String) counField.get(cat);
System.out.println("country的值为:"+country);//country的值为:中国
nameField.setAccessible(true);
String name = (String) nameField.get(cat);//报错IllegalAccessException:访问权限被拒绝,name为私有变量,需要暴力反射
System.out.println("name的值为:"+ name);//name的值为:null
nameField.set(cat,"小花");
String name1 = (String) nameField.get(cat);
System.out.println("name1的值为:"+ name1);//name1的值为:小花
}
}
2.4 获取成员方法
Class提供了从类中获取成员方法的API
方法 | 说明 |
---|---|
Method[] getMethods() | 获取类的全部公共成员方法(只能获取public修饰的) |
Method[] getDeclaredMethods() | 获取类的全部成员方法(只要存在就能拿到) |
Method getMethod(String name, Class<?>... parameterTypes) | 获取类的某个公共成员方法(只能获取public修饰的) |
Method getDeclaredMethod(String name, Class<?>... parameterTypes) | 获取类的某个成员方法(只要存在就能拿到) |
成员方法的作用:依然是执行
Method提供的方法 | 说明 |
---|---|
public Object invoke(Object obj, Object... args) | 触发某个对象的该方法执行。 |
public void setAccessible(boolean flag) | 设置为true,表示禁止检查访问控制(暴力反射) |
获取成员方法[Class提供] Method[] getMethods() 获取类的全部公共成员方法(只能获取public修饰的) Method[] getDeclaredMethods() 获取类的全部成员方法(只要存在就能拿到) Method getMethod(String name, Class<?>... parameterTypes) 获取类的某个公共成员方法(只能获取public修饰的) Method getDeclaredMethod(String name, Class<?>... parameterTypes) 获取类的某个成员方法(只要存在就能拿到) 使用成员方法(执行方法)[Method提供] public Object invoke(Object obj, Object... args) 触发某个对象的该方法执行。 public void setAccessible(boolean flag) 设置为true,表示禁止检查访问控制(暴力反射) 注意 使如果想使用private修饰的成员方法,需要暴力反射
public class Demo4 {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
//1.获取类class对象
Class<Cat> catClass = Cat.class;
// Method[] getMethods() 获取类的全部公共成员方法(只能获取public修饰的)
Method[] method = catClass.getMethods();
System.out.println("全部公共成员方法个数:"+method.length);
for (Method method1 : method) {
System.out.println("============");
System.out.println("方法名字:"+method1.getName() + " 参数个数:"+method1.getParameterCount()
+ " 返回值类型:" + method1.getReturnType());
}
System.out.println();
// Method[] getDeclaredMethods() 获取类的全部成员方法(只要存在就能拿到)
Method[] declaredMethod = catClass.getDeclaredMethods();
System.out.println("全部成员方法个数:"+declaredMethod.length);
for (Method method1 : declaredMethod) {
System.out.println("============");
System.out.println("方法名字:"+method1.getName() + " 参数个数:"+method1.getParameterCount()
+ " 返回值类型:" + method1.getReturnType());
}
System.out.println();
// Method getMethod(String name, Class<?>... parameterTypes) 获取类的某个公共成员方法(只能获取public修饰的)
// Method getDeclaredMethod(String name, Class<?>... parameterTypes) 获取类的某个成员方法(只要存在就能拿到)
Method method1 = catClass.getDeclaredMethod("eat", String.class);
System.out.println("方法名字:"+method1.getName() + " 参数个数:"+method1.getParameterCount()
+ " 返回值类型:" + method1.getReturnType());
// 使用成员方法(执行方法)
//创建对象
Cat cat = new Cat();
method1.setAccessible(true);
String str = (String) method1.invoke(cat, "猫粮");
System.out.println(str);
}
}
运行结果:
全部成员方法个数:8
============
方法名字:getName 参数个数:0 返回值类型:class java.lang.String
============
方法名字:run 参数个数:0 返回值类型:void
============
方法名字:toString 参数个数:0 返回值类型:class java.lang.String
============
方法名字:setName 参数个数:1 返回值类型:void
============
方法名字:setAge 参数个数:1 返回值类型:void
============
方法名字:getAge 参数个数:0 返回值类型:int
============
方法名字:eat 参数个数:1 返回值类型:class java.lang.String
============
方法名字:eat 参数个数:0 返回值类型:void
方法名字:eat 参数个数:1 返回值类型:class java.lang.String
无参数构造器执行了~~
🐱最爱吃:猫粮
2.5 反射的作用
基本作用 可以得到一个类的全部成分然后操作。 可以破坏封装性,也可以破坏泛型的约束性。 最重要的用途是 适合做Java的框架,基本上,主流的框架都会基于反射设计出一些通用的功能。
反射案例 对于任意一个对象,该框架都可以把对象的字段名和对应的值,然后打印在控制台 实现步骤 定义一个方法,可以接收任意对象 每收到一个对象后,使用反射获取该对象的Class对象,然后获取全部的成员变量 遍历成员变量,然后提取成员变量在该对象中的具体值 把成员变量名、和其值,打印到控制台即可
public class Demo5 {
public static void main(String[] args) throws IllegalAccessException {
//1. 准备两个对象
Student student = new Student("柳岩", 40, '女', 167.5, "女星");
Teacher teacher = new Teacher("播妞", 6000);
//2.调用方法
printObject(student);
printObject(teacher);
}
// 定义一个方法,可以接收任意对象
public static void printObject(Object obj) throws IllegalAccessException {
//1. 获取对象的Class对象
Class<?> clazz = obj.getClass();
//1.2 获取类的名字
String simpleName = clazz.getSimpleName();
System.out.println("=======================" + simpleName + "=======================");
//2. 获取全部的成员变量
Field[] declaredFields = clazz.getDeclaredFields();
//3. 遍历全部的成员变量
for (Field declaredField : declaredFields) {
declaredField.setAccessible(true);//暴力反射
//4. 获取成员变量名和对应的值
String name = declaredField.getName();
Object o = declaredField.get(obj);
// 5. 打印到控制台
System.out.println(name + "=" + o);
}
}
}
class Student{
public Student(String name, int age, char sex, double height, String hobby) {
this.name = name;
this.age = age;
this.sex = sex;
this.height = height;
this.hobby = hobby;
}
private String name;
private int age;
private char sex;
private double height;
private String hobby;
}
class Teacher {
public Teacher(String name, double salary) {
this.name = name;
this.salary = salary;
}
private String name;
private double salary;
}
三、注解Annotation
注解: 是Java代码里的特殊标记,比如:@Override、@Test等 这些标记会被特定的注解解析器所发现,进而决定应该怎样去编译或者执行被注解标记出来的程序 作用是对Java中类、方法、成员变量做标记,然后进行特殊处理
注解的解析:判断类上、方法上、成员变量上是否存在注解,并把注解里的内容给解析出来。 如何解析注解? 指导思想:要解析谁上面的注解,就应该先拿到谁 比如要解析类上面的注解,则应该先获取该类的Class对象,再通过Class对象解析其上面的注解 比如要解析成员方法上的注解,则应该获取到该成员方法的Method对象,再通过Method对象解析其上面的注解 Class 、 Method 、 Field , Constructor、都实现了AnnotatedElement接口,它们都拥有解析注解的能力
AnnotatedElement接口提供了解析注解的方法 | 说明 |
---|---|
public Annotation[] getDeclaredAnnotations() | 获取当前对象上面的注解。 |
public T getDeclaredAnnotation(Class<T> annotationClass) | 获取指定的注解对象 |
public boolean isAnnotationPresent(Class<Annotation> annotationClass) | 判断当前对象上是否存在某个注解 |
解析注解的案例
需求如下
定位到指定包中所有带@ClassNameCheck注解的类,然后判断类名是否是以Heima开头,如果不是,就抛异常
下面分析一下步骤
①定义一个类叫ClassNameCheckParser,在类中定义一个checkClassName方法,用来完成功能
②获取项目中指定包下的所有类(此功能已经在工具类中提供好了方法,可以直接使用)
③遍历得到每一个类,然后判断类上是否有@ClassNameCheck注解
④如果有注解,则获取到类名进行判断,如果不符合规范,则放到一个准备好的集合中
⑤等到遍历结束,查看集合中是否有元素;有就说明存在不符合规范的类名;打印结果,抛出异常
public class ClassNameCheckParse {
public void CheckClassName(){
//创建一个集合,用于存放不符合规范的类名
HashSet<String> nameSet = new HashSet<>();
//传入包的名字,获取包下的所有类对象的集合
Set<Class> classSet = ClassUtil.getClasses("com.itheima.c_annotation.example");
//遍历类,判断是否有ClassNameCheck注解
for (Class clazz : classSet) {
//判断类对象上是否有注解
boolean b = clazz.isAnnotationPresent(ClassNameCheck.class);
if(b){
//获取类的名字
String className = clazz.getSimpleName();
//判断类名是否符合规范,以“Hema”开头,如果不符合,就放入集合
if(!className.startsWith("Hema")){
nameSet.add(className);
}
}
}
//判断集合是否为空,如果不为空,就打印并抛出异常
if(nameSet.size()>0){
for (String name : nameSet) {
System.out.println("不符合规范的类名:"+name);
}
throw new RuntimeException("类名不符合规范");
}
}
}
解析注解的案例改进
需求如下:
在定位到有问题的类名的时候,要打印出类的开发者和作用
下面分析一下步骤
①修改@ClassNameLimit注解,添加author和value属性
②修改解析器的类,解析出代码的开发者和作用,并打印出来
public class ClassNameCheckParse {
public void CheckClassName(){
//创建一个集合,用于存放不符合规范的类名
HashSet<String> nameSet = new HashSet<>();
//传入包的名字,获取包下的所有类对象的集合
Set<Class> classSet = ClassUtil.getClasses("com.itheima.c_annotation.example");
//遍历类,判断是否有ClassNameCheck注解
for (Class clazz : classSet) {
//判断类对象上是否有注解
boolean b = clazz.isAnnotationPresent(ClassNameCheck.class);
if(b){
//获取类的名字
String className = clazz.getSimpleName();
//判断类名是否符合规范,以“Heima”开头,如果不符合,就放入集合
if(!className.startsWith("Heima")){
//使用反射获取注解对象
ClassNameCheck cnc = (ClassNameCheck)clazz.getDeclaredAnnotation(ClassNameCheck.class);
//使用注解对象的value属性,获取注解的属性值
String[] author = cnc.author();
String value = cnc.value();
nameSet.add(className + ",作者:" + Arrays.toString(author) + ",作用:" + value);
}
}
}
//判断集合是否为空,如果不为空,就打印并抛出异常
if(nameSet.size()>0){
for (String name : nameSet) {
System.out.println("不符合规范的类名:"+name);
}
throw new RuntimeException("类名不符合规范");
}
}
}