lombok
- Lombok 是一个开源库,它通过注解的方式为 Java 类提供了简洁的方法、属性等简单操作的代码,从而简化了 Java 程序员的代码编写。使用 Lombok 可以通过简单的注解来自动生成在 Java 开发中经常需要的方法,如 Getter/Setter、ToString、EqualsAndHashCode 等,从而减少了 Java 程序员的代码量并且更加优雅。
- Lombok 为 Java 开发提供了很多实用的注解,以下是 Lombok 支持的主要注解:
@Getter 和 @Setter:用于自动生成 JavaBean 的 getter 和 setter 方法。@ToString:用于自动生成 toString() 方法。@EqualsAndHashCode:自动生成 equals 和 hashCode 方法。@NoArgsConstructor:自动生成无参数构造函数。@AllArgsConstructor:自动生成全参数构造函数。@Data:自动生成 setter/getter、equals()、hashCode()、toString() 等方法。@Builder:使用 Builder 方式构建对象。@Slf4j:自动生成 log 对象,可直接使用 log 输出日志。
反射
- Java 反射(Reflection)是 Java 语言的一种机制,它允许在运行时(程序运行过程中)动态地获取类的信息,并可以操作类、对象、方法等。Java 反射为我们提供了一种机制,可以在编译时无法确定类名、方法名、成员变量等信息的情况下,通过运行时获取相关信息并进行处理操作。
- Java 反射的优点在于,它可以在程序运行时,根据条件动态地加载某个类,并获取类的信息并创建对象实例,从而提供了更大的灵活性和扩展性,例如通过反射机制实现 IOC(控制反转)和 AOP(面向切面编程)等,这在很多框架和应用中得到了广泛的应用。但是,由于反射操作需要消耗大量的计算资源,所以在实际的开发中应当谨慎使用,尽量使用直接的操作方式来提高程序的性能和效率。
package note.reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ReflectionNote {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
Class<?> personClass = Class.forName("note.reflection.Person");
personClass = Person.class;
personClass = new Person().getClass();
System.out.println("personClass = " + personClass);
Person person = (Person) personClass.newInstance();
Constructor<?> personConstructor = personClass.getConstructor(String.class, int.class);
System.out.println("personConstructor = " + personConstructor);
Person noby = (Person) personConstructor.newInstance("noby", 20);
Person kace = (Person) personClass.getConstructor().newInstance();
System.out.println("noby = " + noby);
System.out.println("kace = " + kace);
Field name = personClass.getDeclaredField("name");
System.out.println("name = " + name);
Field[] declaredFields = personClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println("declaredField = " + declaredField);
}
name.setAccessible(true);
name.set(kace, "kace");
Method show = personClass.getDeclaredMethod("show", null);
Method say = personClass.getDeclaredMethod("say", String.class, int.class);
Method[] declaredMethods = personClass.getDeclaredMethods();
show.invoke(kace, null);
String hi = (String) say.invoke(kace, "hi",2);
System.out.println(hi);
}
}
package note.reflection;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
class Person {
private String name;
private int age;
private static int numOfEyes;
public void show() {
System.out.println(name + "," + age);
}
public void say(String info, int num) {
System.out.println("say " + info + ",I have say " + num + " times");
}
}
注解
- 允许我们在 Java 程序中加入元数据(Metadata)信息,也就是给程序的注释加上更多的含义。Java 注解本质上是一种标记,可以通过反射机制在程序运行期获取类、方法、字段等的注解信息,并使用这些注解信息完成相应的处理操作。
package note.annotation;
public class AnnotationNote {
public static void main(String[] args) {
DataSource dataSource = JdbcUtil.GetInstance(DataSource.class);
System.out.println("dataSource = " + dataSource);
DataSource2 dataSource2 = JdbcUtil.GetInstance2(DataSource2.class);
System.out.println("dataSource2 = " + dataSource2);
}
}
package note.annotation;
import note.annotation.anno.Jdbc;
import note.annotation.anno2.Driver;
import note.annotation.anno2.Pwd;
import note.annotation.anno2.Url;
import note.annotation.anno2.Username;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
class JdbcUtil {
public static <T> T GetInstance(Class<?> clazz) {
Object dataSource = null;
try {
dataSource = clazz.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
if (clazz.isAnnotationPresent(Jdbc.class)) {
Jdbc annotation = clazz.getAnnotation(Jdbc.class);
((DataSource) dataSource).setDataSourceDriver(annotation.driver());
((DataSource) dataSource).setDataSourceUrl(annotation.url());
((DataSource) dataSource).setDataSourceUsername(annotation.username());
((DataSource) dataSource).setDataSourcePwd(annotation.pwd());
}
return (T) dataSource;
}
public static <T> T GetInstance2(Class<?> clazz) {
Object dataSource = null;
try {
dataSource = clazz.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(Driver.class)) {
String value = field.getAnnotation(Driver.class).value();
String methodName = "set"
+ field.getName().substring(0, 1).toUpperCase()
+ field.getName().substring(1);
try {
Method method = clazz.getDeclaredMethod(methodName, field.getType());
method.invoke(dataSource, value);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
field.setAccessible(true);
try {
field.set(dataSource, value);
} catch (IllegalAccessException illegalAccessException) {
illegalAccessException.printStackTrace();
}
}
} else if (field.isAnnotationPresent(Url.class)) {
} else if (field.isAnnotationPresent(Username.class)) {
} else if (field.isAnnotationPresent(Pwd.class)) {
}
}
return (T) dataSource;
}
}
package note.annotation;
import lombok.Data;
import note.annotation.anno.Jdbc;
@Data
@Jdbc(url = "othersUrl")
class DataSource {
private String dataSourceDriver;
private String dataSourceUrl;
private String dataSourceUsername;
private String dataSourcePwd;
}
package note.annotation.anno;
import java.lang.annotation.*;
@Target(value = {ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface Jdbc {
String driver() default "com.mysql.jdbc.Driver";
String url() default "jdbc:mysql://localhost:3306/stage1";
String username() default "root";
String pwd() default "123";
}
package note.annotation;
import lombok.Data;
import note.annotation.anno2.Driver;
import note.annotation.anno2.Pwd;
import note.annotation.anno2.Url;
import note.annotation.anno2.Username;
@Data
class DataSource2 {
@Driver(value = "driver1")
private String dataSourceDriver;
@Url("url1")
private String dataSourceUrl;
@Username("username1")
private String dataSourceUsername;
@Pwd("pwd1")
private String dataSourcePwd;
}
package note.annotation.anno2;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(value = {ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Driver {
String value() default "";
}
package note.annotation.anno2;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(value = {ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Pwd {
String value() default "";
}
package note.annotation.anno2;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(value = {ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Url {
String value() default "";
}
package note.annotation.anno2;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(value = {ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Username {
String value() default "";
}
枚举
- 定义:枚举(Enum)是一种特殊的数据类型,它定义了一组有限的常量值,每个常量都是枚举类型的实例,可以通过枚举常量名来引用它们。
- 枚举常量可以具有属性,方法和构造函数,这使得它们可以像类一样进行扩展。枚举类型的实例是单例的,因此可以将它们用作常量,而不必担心实例化多个相同值的对象。
- 枚举类型在 Java 中有广泛的应用,例如表示一组相关的常量值,状态机等。使用枚举类型可以提高代码的可读性和可维护性,避免使用魔法数字和字符串常量。
package note.emun;
public class EnumNote {
public static void main(String[] args) {
MyColor red = MyColor.RED;
System.out.println("red = " + red);
System.out.println("red.getValue() = " + red.getValue());
red.setValue("大红色");
System.out.println("red = " + red);
System.out.println("red.getValue() = " + red.getValue());
switch (red) {
case RED:
System.out.println("选择了RED");
break; case YELLOW:
System.out.println("选择了YELLOW");
break; default:
break;
}
}
}
package note.emun;
enum MyColor {
RED("红色"), YELLOW("黄色"), BLUE("蓝色"), ORANGE("橘色");
private String value;
MyColor(String value) {
this.value = value;
}
public void method() {
System.out.println("MyColor method");
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}