Java存在哪些工具或库,它们仅使用interface
访问器方法定义并自动生成不可变对象类,还有一个“构建器”类,用于通过创建新实例来增量构建新实例或更改现有实例的?
示例输入:
public interface Car {
String getModelName();
int getWheelCount();
}
示例输出:
import javax.annotation.concurrent.Immutable;
import javax.annotation.concurrent.NotThreadSafe;
@Immutable
public final class ImmutableCar implements Car {
@NotThreadSafe
public static final class Builder implements Car {
private String modelName;
private int wheelCount;
public Builder() {
}
public Builder(final Car car) {
modelName = car.getModelName();
wheelCount = car.getWheelCount();
}
public ImmutableCar build() {
return new ImmutableCar(wheelCount, modelName);
}
@Override
public String getModelName() {
return modelName;
}
@Override
public int getWheelCount() {
return wheelCount;
}
public void setModelName(final String modelName) {
this.modelName = modelName;
}
public void setWheelCount(final int wheelCount) {
this.wheelCount = wheelCount;
}
}
private final String modelName;
private final int wheelCount;
public ImmutableCar(final int wheelCount, final String modelName) {
this.wheelCount = wheelCount;
this.modelName = modelName;
}
@Override
public String getModelName() {
return modelName;
}
@Override
public int getWheelCount() {
return wheelCount;
}
}
答案 0 :(得分:3)
Google
有一个名为AutoValue的工具可以执行此操作,除非基于抽象基类而不是接口。
import com.google.auto.value.AutoValue;
class Example {
@AutoValue
abstract static class Animal {
static Builder builder() {
return new AutoValue_Example_Animal.Builder();
}
abstract String name();
abstract int numberOfLegs();
@AutoValue.Builder
abstract static class Builder {
abstract Builder name(String s);
abstract Builder numberOfLegs(int n);
abstract Animal build();
}
}
}
另一个类似的工具是Immutables;这可能是与问题更接近的匹配,因为它使用接口并生成不可变的实现和构建器。
答案 1 :(得分:2)
Lombok允许这样的代码:
@lombok.Data
@lombok.Builder
public class ImmutableCar implements Car {
private final @lombok.NonNull String modelName;
private final @lombok.NonNull int wheelCount;
}
在编译时处理lombok注释(JSR-269)以生成完整的类。也可以通过' delomboking'来查看生成的代码。通过Maven插件。
答案 2 :(得分:1)
查看Eclipse Model2Text project及其子项目,尤其是Acceleo和Xpand。它们通常用于为EMF模型生成基于EMF的Java代码,但它们也可用于生成简单的POJO。
但是这个功能并不是开箱即用的:你必须为它创建自己的代码生成器和模板。见Accelelo tutorial。
编辑:
还有一个想法 - 一个如此简单,以至于我花了一天才意识到它您可以使用Velocity,Freemarker或类似的模板库(通常用于生成html)。虽然你仍然需要在某个地方创建一个模型,例如.txt或.xml文件。这是一个tutorial on Velocity code generation。
答案 3 :(得分:1)
我刚创建了一个eclipse插件https://github.com/karajdaar/templator。
它基于Freemarker模板生成代码。 Freemarker模板的上下文是ICompilationUnit,它允许完全访问命名类及其信息。我们正在使用它为NoSQL数据库,球衣客户端,测试等生成DAO。
我认为这很容易做到这里所需要的。
答案 4 :(得分:1)
Immutables(http://immutables.github.io)注释处理器完全符合您的需求。它功能齐全且可定制(你知道所有set
vs with
vs无前缀战争, - 使用你喜欢的任何东西)。它可以使用接口,抽象类,注释的构建器生成不可变的实现。此外,它还可以生成构建器以调用静态工厂方法或POJO构造函数以及许多其他内容。
@Value.Immutable
public interface ValueObject {
String name();
List<Integer> counts();
Optional<String> description();
}
// Compile using annotation processor and use it like this
ValueObject valueObject =
ImmutableValueObject.builder()
.name("My value")
.addCounts(1)
.addCounts(2)
.build();