单元测试
就是针对最小的功能单元(方法),编写测试代码对其进行正确性测试。
咱们之前是如何进行单元测试的? 有啥问题 ?
- 只能在main方法编写测试代码,去调用其他方法进行测试。
- 无法实现自动化测试,一个方法测试失败,可能影响其他方法的测试。
- 无法得到测试的报告,需要程序员自己去观察测试是否成功。
Junit单元测试框架
可以用来对方法进行测试,它是由Junit公司开源出来的
优点
- 可以灵活的编写测试代码,可以针对某个方法执行测试,也支持一键完成对全部方法的自动化测试,且各自独立。
- 不需要程序员去分析测试的结果,会自动生成测试报告出来。
Junit单元测试-快速入门
package com.itheima.a_单元测试;
import org.junit.*;
public class StringUtilTest {
/*===调用initClass方法===
===调用init方法===
2
===测试方法调用结束===
===调用init方法===
名字长度:5
名字长度:3
名字长度:0
===测试方法调用结束===
===endClass===
*/
@Before
//在测试方法执行前执行的方法,常用于:初始化资源。
public void init() {
System.out.println("===调用init方法===");
}
@After
//在测试方法执行完后再执行的方法,常用于:释放资源。
public void end() {
System.out.println("===测试方法调用结束===");
}
@BeforeClass
public static void initClass() {
System.out.println("===调用initClass方法===");
}
@AfterClass
public static void endClass() {
System.out.println("===endClass===");
}
@Test
public void testprintNumber() {
//直接用类名调用
StringUtil.printNumber("jacky");
StringUtil.printNumber("李铁牛");
StringUtil.printNumber("");
// StringUtil.printNumber(null);
}
@Test
public void testgetMaxIndex() {
int maxIndex = new StringUtil().getMaxIndex("jacky");
// Assert.assertEquals("最大索引不符合预期", 2, maxIndex);
int maxIndex1 = new StringUtil().getMaxIndex("翠花");
System.out.println(maxIndex1);
int maxIndex2 = new StringUtil().getMaxIndex("");
int maxIndex3 = new StringUtil().getMaxIndex(null);
}
}
public class StringUtil {
//获取字符串长度
public static void printNumber(String name) {
System.out.println("名字长度:" + name.length());
}
//获取字符串的最大索引
public int getMaxIndex(String data) {
if (data == null) {
return -1;
}
return data.length();
}
}
1、Junit单元测试是做什么的?
测试类中方法的正确性的
2、JUnit单元测试的实现过程是什么样的?
必须导入Junit框架的jar包
定义的测试方法必须是无参数无返回值,且公开的方法
测试方法使用@Test注解标记
3、JUnit测试某个方法,测试全部方法怎么处理?成功的标志是什么?
测试某个方法直接右键该方法启动测试
测试全部方法,可以选择类或者模块启动
红色失败,绿色通过
Junit框架的常见注释
Junit单元测试框架的常用注解(Junit 4.xxxx版本)
注解 | 说明 |
@Test | 测试类中的方法必须用它修饰才能成为测试方法,才能启动执行 |
@Before | 用来修饰一个实例方法,该方法会在每一个测试方法执行之前执行一次。 |
@After | 用来修饰一个实例方法,该方法会在每一个测试方法执行之后执行一次。 |
@BeforeClass | 用来修饰一个静态方法,该方法会在所有测试方法之前只执行一次。 |
@AfterClass | 用来修饰一个静态方法,该方法会在所有测试方法之后只执行一次。 |
- 在测试方法执行前执行的方法,常用于:初始化资源。
- 在测试方法执行完后再执行的方法,常用于:释放资源。
Junit单元测试框架的常用注解(Junit 5.xxxx版本)
注解 | 说明 |
---|---|
@Test | 测试类中的方法必须用它修饰才能成为测试方法,才能启动执行 |
@BeforeEach | 用来修饰一个实例方法,该方法会在每一个测试方法执行之前执行一次。 |
@AfterEach | 用来修饰一个实例方法,该方法会在每一个测试方法执行之后执行一次。 |
@BeforeAll | 用来修饰一个静态方法,该方法会在所有测试方法之前只执行一次。 |
@AfterAll | 用来修饰一个静态方法,该方法会在所有测试方法之后只执行一次。 |
- 开始执行的方法:初始化资源
- 执行完之后的方法:释放资源
反射
反射(Reflection)
- 反射就是:加载类,并允许以编程的方式解剖类中的各种成分(成员变量、方法、构造器等)。
反射学什么?
获取Class对象的三种方式
- 直接使用类名.class获取:Class c1 = 类名.class
- 调用Class提供的方法:Class c2 = Class.forName("全类名")
- 调用Object提供的方法:Class c3 = 对象.getClass()
/*
反射的第一步是什么
获取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> catClass = Cat.class;
System.out.println(catClass);
//2. 调用Class提供的方法:Class c2 = Class.forName("全类名")
Class<?> aClass = Class.forName("com.itheima.b_反射.Cat");
System.out.println(aClass);
//3. 调用Object提供的方法:Class c3 = 对象.getClass()
Cat cat = new Cat();
Class<? extends Cat> aClass1 = cat.getClass();
System.out.println(aClass1);
System.out.println(aClass1.getName());
System.out.println(aClass1.getSimpleName());
}
}
1、反射的第一步是什么?
获取Class类对象,如此才可以解析类的全部成分
2、获取Class类对象的三种方式是啥?
Class c1 = 类名.class
Class c2 = Class.forName("全类名");
Class c3 = 对象.getClass();
获取类的构造器
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 {
//创建获取类Class对象
Class<Cat> catClass = Cat.class;
//Constructor<?>[] getConstructors() 获取所有的公共构造器(只能获取public修饰的)
Constructor<?>[] constructors = catClass.getConstructors();
System.out.println(constructors.length);
//Constructor<?>[] getDeclaredConstructors() 获取全部构造器(只要存在就能拿到)
Constructor<?>[] declaredConstructors = catClass.getDeclaredConstructors();
System.out.println(declaredConstructors);
for (Constructor<?> declaredConstructor : declaredConstructors) {
System.out.println(declaredConstructor.getName());
System.out.println(declaredConstructor.getParameterCount());
}
//Constructor<T> getConstructor(Class<?>... parameterTypes) 获取某个公共构造器(只能获取public修饰的)
Constructor<Cat> constructor = catClass.getConstructor();
System.out.println(constructor.getParameterCount());
Constructor<Cat> constructor1 = catClass.getConstructor(String.class);
System.out.println(constructor1.getParameterCount());
// Constructor<Cat> constructor2 = catClass.getConstructor(int.class, String.class);//NoSuchMethodException,没有得不到这个参数构造器
// System.out.println(constructor2.getParameterCount());
//Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 获取某个构造器(只要存在就能拿到)
Constructor<Cat> declaredConstructor = catClass.getDeclaredConstructor(String.class, int.class);
System.out.println(declaredConstructor.getParameterCount());
//创建Cat对象,使用构造器对象,公共无参
Cat cat = constructor.newInstance();
System.out.println(cat);
System.out.println("============");
//使用私有构造器对象,创建对象
//暴力反射
declaredConstructor.setAccessible(true);
Cat cat1 = declaredConstructor.newInstance("狸花猫", 2);
System.out.println(cat1);
}
}
1、如何去获取类的构造器?
Constructor<?>[] getDeclaredConstructors()
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
2、获取到类的构造器,有啥作用?
T newInstance(Object... initArgs)
public void setAccessible(boolean flag)
获取类的成员变量
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 {
//第一步,获取Class对象
Class<Cat> catClass = Cat.class;
// public Field[] getFields() 获取类的所有公共成员变量(只能获取public修饰的)
// public Field[] getDeclaredFields() 获取类的全部成员变量(只要存在就能拿到)
Field[] declaredFields = catClass.getDeclaredFields();
System.out.println("变量个数=" + declaredFields.length);
for (Field declaredField : declaredFields) {
System.out.println(declaredField.getName() + ",类型" + declaredField.getType());
}
// public Field getField(String name) 获取类的某个公共成员变量(只能获取public修饰的)
// public Field getDeclaredField(String name) 获取类的某个成员变量(只要存在就能拿到)
Field aField = catClass.getDeclaredField("a");
System.out.println(aField.getName() + "-" + aField.getType());
Field nameField = catClass.getDeclaredField("name");
System.out.println(nameField.getName() + "-" + nameField.getType());
Field countryField = catClass.getDeclaredField("COUNTRY");
System.out.println(countryField.getName() + "-" + countryField.getType());
//创建对象
Cat cat = new Cat();
System.out.println(cat);
int a = (int) aField.get(cat);
System.out.println(a);
String country = (String) countryField.get(cat);
System.out.println(country);
//暴力反射 需要获取私有参数
nameField.setAccessible(true);
String name = (String) nameField.get(cat);
System.out.println(name);
aField.set(cat,88);
int a1 = (int) aField.get(cat);
System.out.println(a1);
nameField.set(cat,"丧彪");
String name1 = (String) nameField.get(cat);
System.out.println(name1);
}
}
1、如何去获取类的成员变量?
getDeclaredFields()
getDeclaredField (String name)
2、获取到类的成员变量,有啥作用?
void set(Object obj, Object value)
Object get(Object obj)
setAccessible(boolean)
获取类的成员方法
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 {
Class<Cat> catClass = Cat.class;
Method[] declaredMethods = catClass.getDeclaredMethods();
//有几个方法
// System.out.println(declaredMethods.length);
//每个方法的名字和返回类型
// for (Method declaredMethod : declaredMethods) {
// System.out.println("方法名字:" + declaredMethod.getName() + "返回类型:" + declaredMethod.getReturnType());
// }
Method eatMethod = catClass.getDeclaredMethod("eat", String.class);
System.out.println(eatMethod.getReturnType());//class java.lang.String 得到私有方法
//得到该方法中的参数类型
Class<?>[] parameterTypes = eatMethod.getParameterTypes();
// for (Class<?> parameterType : parameterTypes) {
// System.out.println(parameterType.getName());
// }
Cat cat = new Cat();
//暴力反射
eatMethod.setAccessible(true);
String str = (String) eatMethod.invoke(cat, "巴西果冻");
System.out.println(str);
}
}
反射的作用?
- 基本作用:可以得到一个类的全部成分然后操作。
- 可以破坏封装性。
- 最重要的用途是:适合做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.调用方法
printObj(student);
printObj(teacher);
}
public static void printObj(Object obj) throws IllegalAccessException {
Class<?> clazz = obj.getClass();
String name = clazz.getSimpleName();
System.out.println("===========" + name + "===========");
Field[] declaredFields = clazz.getDeclaredFields();
for (Field declaredField : declaredFields) {
declaredField.setAccessible(true);
System.out.println(declaredField.getName() + "=" + declaredField.get(obj));
}
}
}
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;
}
- 可以在运行时得到一个类的全部成分然后操作
- 可以破坏封装性
- 也可以破坏泛型的约束性
- 更重要的用途是适合:做Java高级框架
- 基本上主流框架都会基于反射设计一些通用技术功能
注解(Annotation)
- 就是Java代码里的特殊标记,比如:@Override、@Test等
- 这些标记会被特定的注解解析器所发现,进而决定应该怎样去编译或者执行被注解标记出来的程序
自定义注解格式
注解本质是一个接口,Java中所有注解都是继承了Annotation接口的。
元注解
指的是:修饰注解的注解,可以指定注解的标注位置和保留阶段
@Target({ElementType.FIELD,ElementType.METHOD,ElementType.TYPE})//标记作用的位置
@Retention(RetentionPolicy.RUNTIME)//标记存货阶段
public @interface ClassNameCheck {
public String[] author() default "heihei";
public String value() ;
}
什么是注解的解析?
- 就是判断类上、方法上、成员变量上是否存在注解,并把注解里的内容给解析出来。
如何解析注解?
- 指导思想:要解析谁上面的注解,就应该先拿到谁
- 比如要解析类上面的注解,则应该先获取该类的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(author = "heiyang",value = "simida")
public class Teacher {
private String name;
private Integer age;
public String sayHello() {
return "hello";
}
}
//ClassNameCheckParse类
public class ClassNameCheckParse {
public void checkClassName() {
//创建存放不符合要求的类名的集合
Set<String> nameSet = new HashSet<>();
//传入包名字,获取包下的所有类对象集合
Set<Class> clazzSet = ClassUtil.getClasses("com.itheima.c_annotation.example");
for (Class clazz : clazzSet) {
boolean flag = clazz.isAnnotationPresent(ClassNameCheck.class);
if (flag) {
//获取类名字
String className = clazz.getSimpleName();
//判断类名字是否符合规范,如果不符合,就放入集合
if (!className.startsWith("Heima")) {
//使用反射获取,注解对象
ClassNameCheck cnc = (ClassNameCheck) clazz.getDeclaredAnnotation(ClassNameCheck.class);
//使用注解对象获取属性值
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("类名不符合规范");
}
}
}
//自定义注释
@Target({ElementType.FIELD,ElementType.METHOD,ElementType.TYPE})//标记作用的位置
@Retention(RetentionPolicy.RUNTIME)//标记存货阶段
public @interface ClassNameCheck {
public String[] author() default "诸葛马懿";
public String value() ;
}
//Class工具类
public class ClassUtil {
private ClassUtil() {
}
/**
* 获取某个包下的所有类
*/
public static Set<Class> getClasses(String packageName) {
try {
Set<Class> classSet = new HashSet<>();
Enumeration<URL> urls = Thread.currentThread().getContextClassLoader().getResources(packageName.replace(".", "/"));
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
if (url != null) {
String protocol = url.getProtocol();
if (protocol.equals("file")) {
String packagePath = url.getPath().replaceAll("%20", " ");
addClass(classSet, packagePath, packageName);
} else if (protocol.equals("jar")) {
JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection();
if (jarURLConnection != null) {
JarFile jarFile = jarURLConnection.getJarFile();
if (jarFile != null) {
Enumeration<JarEntry> jarEntries = jarFile.entries();
while (jarEntries.hasMoreElements()) {
JarEntry jarEntry = jarEntries.nextElement();
String jarEntryName = jarEntry.getName();
if (jarEntryName.endsWith(".class")) {
String className = jarEntryName.substring(0, jarEntryName.lastIndexOf(".")).replaceAll("/", ".");
doAddClass(classSet, className);
}
}
}
}
}
}
}
return classSet;
} catch (Exception e) {
throw new RuntimeException("包名错误");
}
}
private static void addClass(Set<Class> classSet, String packagePath, String packageName) {
File[] files = new File(packagePath).listFiles(new FileFilter() {
@Override
public boolean accept(File file) {
return (file.isFile() && file.getName().endsWith(".class")) || file.isDirectory();
}
});
for (File file : files) {
String fileName = file.getName();
if (file.isFile()) {
String className = fileName.substring(0, fileName.lastIndexOf("."));
if (StringUtils.isNotEmpty(packageName)) {
className = packageName + "." + className;
}
doAddClass(classSet, className);
} else {
String subPackagePath = fileName;
if (StringUtils.isNotEmpty(packagePath)) {
subPackagePath = packagePath + "/" + subPackagePath;
}
String subPackageName = fileName;
if (StringUtils.isNotEmpty(packageName)) {
subPackageName = packageName + "." + subPackageName;
}
addClass(classSet, subPackagePath, subPackageName);
}
}
}
/**
* 加载类
*/
private static Class loadClass(String className, boolean isInitialized) {
Class cls;
try {
cls = Class.forName(className, isInitialized, getClassLoader());
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
return cls;
}
/**
* 加载类(默认将初始化类)
*/
private static Class loadClass(String className) {
return loadClass(className, true);
}
private static void doAddClass(Set<Class> classSet, String className) {
Class cls = loadClass(className, false);
classSet.add(cls);
}
}
//测试类
public class Test {
public static void main(String[] args) {
ClassNameCheckParse parse = new ClassNameCheckParse();
parse.checkClassName();
System.out.println("吃饱了!");
}
}
注解属性
- 在定义注解的时候,还可以通过属性来进一步描述注解的细节
特殊属性名: value
- 如果注解中只有一个value属性,使用注解时,value名称可以不写!!
@ClassNameCheck(author = {"heiyang","wudi"},value = "simida")
public class Teacher {
private String name;
private Integer age;
public String sayHello() {
return "hello";
}
}
@Target({ElementType.FIELD,ElementType.METHOD,ElementType.TYPE})//标记作用的位置
@Retention(RetentionPolicy.RUNTIME)//标记存货阶段
public @interface ClassNameCheck {
public String[] author() default "zrn";
public String value() ;
}
解析注解的案例改进
需求如下:
在定位到有问题的类名的时候,要打印出类的开发者和作用
下面分析一下步骤:
//测试类 ,也用上边的文件完成
public class Test {
public static void main(String[] args) {
Student student = new Student();
student.setName("芜湖~");
System.out.println(student.getName());
System.out.println("吃饱了!");
}
}
Lombok
- Lombok是一个实用的Java类库,能通过注解的形式自动生成构造器、getter/setter、equals、hashcode、toString等方法,并可以自动化生成日志变量,简化java开发、提高效率。
注解 | 作用 |
@Getter/@Setter | 为所有的属性提供get/set方法 |
@ToString | 会给类自动生成易阅读的 toString 方法 |
@EqualsAndHashCode | 根据类所拥有的非静态字段自动重写 equals 方法和 hashCode 方法 |
@Data | 提供了更综合的生成代码功能(@Getter + @Setter + @ToString + @EqualsAndHashCode) |
@NoArgsConstructor | 为实体类生成无参的构造器方法 |
@AllArgsConstructor | 为实体类生成除了static修饰的字段之外带有各参数的构造器方法。 |
注意:Lombok会在编译时,自动生成对应的java代码。我们使用lombok时,还需要安装一个lombok的插件(idea自带)。
@Data//get和set方法
@NoArgsConstructor//无参构造
@AllArgsConstructor//全参构造
@ClassNameCheck(author = {"baima","lvma"},value = "哇哈哈")
public class Student {
private String name;
private Integer age;
public String sayHello() {
return "hello";
}
}