4

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;
    }

}
4

5 回答 5

3

Google have a tool called AutoValue that does this, except based on an abstract base class instead of an interface.

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();
    }
  }
}

Another similar tool is Immutables; this is probably a closer match to the question, as it uses an interface and generates an immutable implementation and a builder.

于 2015-07-02T09:59:39.187 回答
3

Immutables (http://immutables.github.io) annotation processor is the exact match for your needs. It is full-featured and very customizable (you know all those set vs with vs no-prefix wars, - use whatever you prefer). It can generate immutable implementation with builders for interfaces, abstract classes, annotations. In addition, it can generate builders to invoke static factory methods or POJO constructors and many other things.

@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();
于 2017-03-21T05:41:59.940 回答
2

Lombok allows code like this:

@lombok.Data
@lombok.Builder
public class ImmutableCar implements Car {
    private final @lombok.NonNull String modelName;
    private final @lombok.NonNull int wheelCount;
}

The lombok annotations are processed at compile time (JSR-269) to generate the full class. It is also possible to look at the generated code by 'delomboking' via a Maven plugin.

于 2015-07-02T09:20:12.090 回答
1

查看Eclipse Model2Text 项目及其子项目,尤其是AcceleoXpand。它们通常用于为 EMF 模型生成基于 EMF 的 Java 代码,但它们也可用于生成简单的 POJO。

however this functionality does not come out of the box: you'd have to create your own code generator and templates for it. see Accelelo tutorial .

EDIT:

one more idea - one so simple that it took me a day to realize it

you can use Velocity, Freemarker or similar template library (which are normally used for html generation). though still you need to make a model somewhere, in a .txt or .xml file for example. here's a tutorial on Velocity code generation.

于 2013-02-06T10:58:23.760 回答
1

I just created an eclipse plugin https://github.com/karajdaar/templator.

It generates code based on Freemarker templates. The context to the Freemarker template is a ICompilationUnit which allows fully access to named classes and their information. We are using it to generate DAOs for NoSQL databases, jersey client, tests, etc.

I think it can easily do what is required here.

于 2013-03-21T16:44:12.547 回答