通过注解的方式,在编译时生成代码
类型推导
val
不可变,相当于加了 final
val str = "Hello World";
等价于
final String str = "Hello World";
如果尝试修改
val str = "Hello World";
str = "Hello World ~";
会报错
error: cannot assign a value to final variable str
var
仅类型推导,可变
注解
@NonNull
private void test(@NonNull String str) {
System.out.println(str);
}
编译后
private void test(@NonNull String str) {
if (str == null) {
throw new NullPointerException("str is marked @NonNull but is null");
} else {
System.out.println(str);
}
}
@Cleanup
自动化关闭流
private void test(String inputFile, String outputFile) throws Exception {
@Cleanup val in = new FileInputStream(inputFile);
@Cleanup val out = new FileOutputStream(outputFile);
byte[] b = new byte[10000];
while (true) {
int r = in.read(b);
if (r == -1) break;
out.write(b, 0, r);
}
}
编译后
private void test(String inputFile, String outputFile) throws Exception {
FileInputStream in = new FileInputStream(inputFile);
try {
FileOutputStream out = new FileOutputStream(outputFile);
try {
byte[] b = new byte[10000];
while(true) {
int r = in.read(b);
if (r == -1) {
return;
}
out.write(b, 0, r);
}
} finally {
if (Collections.singletonList(out).get(0) != null) {
out.close();
}
}
} finally {
if (Collections.singletonList(in).get(0) != null) {
in.close();
}
}
}
只有对象中有 clese()
方法就可以用 @Cleanup
@Getter/@Setter
自动添加 set get 方法
在类上添加
@Setter
@Getter
public class Student {
private String name;
private int age;
}
编译后
public class Student {
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return this.name;
}
public int getAge() {
return this.age;
}
}
也可以在单独的属性上加
public class Student {
@Getter
private String name;
@Setter(AccessLevel.PROTECTED)
private int age;
}
编译后
public class Student {
private String name;
private int age;
public String getName() {
return this.name;
}
protected void setAge(int age) {
this.age = age;
}
}
@ToString
@ToString
public class Student {
private String name;
//排除age属性
@ToString.Exclude
private int age;
}
编译后
public class Student {
private String name;
private int age;
public String toString() {
return "T.Student(name=" + this.name + ")";
}
}
其他选项:
callSuper
: 是否调用父类的 toString()
includeFieldNames
: toString()
是否包含属性的名字
@EqualsAndHashCode
@EqualsAndHashCode
public class Student {
private String name;
private int age;
private Family family;
}
编译后
public class Student {
private String name;
private int age;
private Family family;
public boolean equals(Object o) {
if (o == this) {
return true;
} else if (!(o instanceof Student)) {
return false;
} else {
Student other = (Student)o;
if (!other.canEqual(this)) {
return false;
} else {
label39: {
Object this$name = this.name;
Object other$name = other.name;
if (this$name == null) {
if (other$name == null) {
break label39;
}
} else if (this$name.equals(other$name)) {
break label39;
}
return false;
}
if (this.age != other.age) {
return false;
} else {
Object this$family = this.family;
Object other$family = other.family;
if (this$family == null) {
if (other$family != null) {
return false;
}
} else if (!this$family.equals(other$family)) {
return false;
}
return true;
}
}
}
}
protected boolean canEqual(Object other) {
return other instanceof Student;
}
public int hashCode() {
int PRIME = true;
int result = 1;
Object $name = this.name;
int result = result * 59 + ($name == null ? 43 : $name.hashCode());
result = result * 59 + this.age;
Object $family = this.family;
result = result * 59 + ($family == null ? 43 : $family.hashCode());
return result;
}
}
构造方法
@NoArgsConstructor
无参数
@RequiredArgsConstructor
构造方法里的参数是@Nonnull
的属性
@RequiredArgsConstructor(staticName = "of")
public class Student {
@NonNull
private String name;
private int age;
@NonNull
private Family family;
}
编译后
public class Student {
@NonNull
private String name;
private int age;
@NonNull
private Family family;
private Student(@NonNull String name, @NonNull Family family) {
if (name == null) {
throw new NullPointerException("name is marked @NonNull but is null");
} else if (family == null) {
throw new NullPointerException("family is marked @NonNull but is null");
} else {
this.name = name;
this.family = family;
}
}
public static Student of(@NonNull String name, @NonNull Family family) {
return new Student(name, family);
}
}
@AllArgsConstructor
参数是所有属性
@Data
多个注解的汇总,适用于属性可变的数据类
@ToString
@EqualsAndHashCode
所有属性的 @Getter
非 final 属性的 @Setter
@RequiredArgsConstructor
@Data
public class Point {
private float x;
private float y;
private float z;
}
编译后
public class Point {
private float x;
private float y;
private float z;
public float getX() {
return this.x;
}
public float getY() {
return this.y;
}
public float getZ() {
return this.z;
}
public void setX(float x) {
this.x = x;
}
public void setY(float y) {
this.y = y;
}
public void setZ(float z) {
this.z = z;
}
public boolean equals(Object o) {
if (o == this) {
return true;
} else if (!(o instanceof Point)) {
return false;
} else {
Point other = (Point)o;
if (!other.canEqual(this)) {
return false;
} else if (Float.compare(this.getX(), other.getX()) != 0) {
return false;
} else if (Float.compare(this.getY(), other.getY()) != 0) {
return false;
} else {
return Float.compare(this.getZ(), other.getZ()) == 0;
}
}
}
protected boolean canEqual(Object other) {
return other instanceof Point;
}
public int hashCode() {
int PRIME = true;
int result = 1;
int result = result * 59 + Float.floatToIntBits(this.getX());
result = result * 59 + Float.floatToIntBits(this.getY());
result = result * 59 + Float.floatToIntBits(this.getZ());
return result;
}
public String toString() {
return "Point(x=" + this.getX() + ", y=" + this.getY() + ", z=" + this.getZ() + ")";
}
}
@Value
多个注解的汇总,适用于属性不可变的数据类
@ToString
@EqualsAndHashCode
@AllArgsConstructor
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
@Getter
@Value
public class Point {
private float x;
private float y;
private float z;
}
编译后
public final class Point {
private final float x;
private final float y;
private final float z;
public Point(float x, float y, float z) {
this.x = x;
this.y = y;
this.z = z;
}
public float getX() {
return this.x;
}
public float getY() {
return this.y;
}
public float getZ() {
return this.z;
}
public boolean equals(Object o) {
if (o == this) {
return true;
} else if (!(o instanceof Point)) {
return false;
} else {
Point other = (Point)o;
if (Float.compare(this.getX(), other.getX()) != 0) {
return false;
} else if (Float.compare(this.getY(), other.getY()) != 0) {
return false;
} else {
return Float.compare(this.getZ(), other.getZ()) == 0;
}
}
}
public int hashCode() {
int PRIME = true;
int result = 1;
int result = result * 59 + Float.floatToIntBits(this.getX());
result = result * 59 + Float.floatToIntBits(this.getY());
result = result * 59 + Float.floatToIntBits(this.getZ());
return result;
}
public String toString() {
return "Point(x=" + this.getX() + ", y=" + this.getY() + ", z=" + this.getZ() + ")";
}
}
@Builder
builder 模式构建对象
@Builder
public class Student {
private String name;
private int age;
@Singular
private List<Float> scores;
}
编译后
public class Student {
private String name;
private int age;
private List<Float> scores;
Student(String name, int age, List<Float> scores) {
this.name = name;
this.age = age;
this.scores = scores;
}
public static Student.StudentBuilder builder() {
return new Student.StudentBuilder();
}
public static class StudentBuilder {
private String name;
private int age;
private ArrayList<Float> scores;
public Student.StudentBuilder name(String name) {
this.name = name;
return this;
}
public Student.StudentBuilder age(int age) {
this.age = age;
return this;
}
public Student.StudentBuilder score(Float score) {
if (this.scores == null) {
this.scores = new ArrayList();
}
this.scores.add(score);
return this;
}
public Student.StudentBuilder scores(Collection<? extends Float> scores) {
if (this.scores == null) {
this.scores = new ArrayList();
}
this.scores.addAll(scores);
return this;
}
public Student.StudentBuilder clearScores() {
if (this.scores != null) {
this.scores.clear();
}
return this;
}
public Student build() {
List scores;
switch(this.scores == null ? 0 : this.scores.size()) {
case 0:
scores = Collections.emptyList();
break;
case 1:
scores = Collections.singletonList(this.scores.get(0));
break;
default:
scores = Collections.unmodifiableList(new ArrayList(this.scores));
}
return new Student(this.name, this.age, scores);
}
public String toString() {
return "Student.StudentBuilder(name=" + this.name + ", age=" + this.age + ", scores=" + this.scores + ")";
}
}
}
调用时
Student.builder()
.age(20)
.name("Victor")
.score(100f)
.scores(Arrays.asList(90f,80f))
.build();
@SneakyThrows
抛出异常时,在当前方法上调用,不用显示的在方法名后面写 throw
private String test(byte[] bytes) throws UnsupportedEncodingException {
return new String(bytes, "GBK");
}
使用注解
@SneakyThrows(UnsupportedEncodingException.class)
private String test(byte[] bytes) {
return new String(bytes, "GBK");
}
编译后
private String test(byte[] bytes) {
try {
return new String(bytes, "GBK");
} catch (UnsupportedEncodingException var3) {
throw var3;
}
}
@Synchronized
自动加锁,不建议使用
public class T {
private final Object lock = new Object();
@Synchronized
public static void test() {
System.out.println("test");
}
@Synchronized
public int test2() {
return 20;
}
@Synchronized("lock")
public void test3() {
System.out.println("test2");
}
}
编译后
public class T {
private static final Object $LOCK = new Object[0];
private final Object $lock = new Object[0];
private final Object lock = new Object();
public static void test() {
synchronized($LOCK) {
System.out.println("test");
}
}
public int test2() {
synchronized(this.$lock) {
return 20;
}
}
public void test3() {
synchronized(this.lock) {
System.out.println("test2");
}
}
}
@Getter(lazy=true)
懒加载
public class T {
@Getter(lazy = true)
private final double[] cached = expensive();
private double[] expensive() {
double[] result = new double[1000000];
for (int i = 0; i < result.length; i++) {
result[i] = Math.asin(i);
}
return result;
}
}
编译后
public class T {
private final AtomicReference<Object> cached = new AtomicReference();
private double[] expensive() {
double[] result = new double[1000000];
for(int i = 0; i < result.length; ++i) {
result[i] = Math.asin((double)i);
}
return result;
}
public double[] getCached() {
Object value = this.cached.get();
if (value == null) {
synchronized(this.cached) {
value = this.cached.get();
if (value == null) {
double[] actualValue = this.expensive();
value = actualValue == null ? this.cached : actualValue;
this.cached.set(value);
}
}
}
return (double[])(value == this.cached ? null : value));
}
}
Log
包含常用的日志工具类
@CommonsLog
org.apache.commons.logging.Log
@Flogger
com.google.common.flogger.FluentLogger
@JBossLog
@Log
@Log4j
@Log4j2
org.apache.logging.log4j.Logger
@Slf4j
@XSlf4j
@Slf4j
public class T {
private void test() {
log.info("test");
}
}
编译后
public class T {
private static final Logger log = LoggerFactory.getLogger(T.class);
private void test() {
log.info("test");
}
}