Короткий ответ нет. То, о чем вы просите, невозможно. Reflection рассматривает код во время выполнения и динамически вызывает методы, он не может генерировать фактические методы.
Что вы могли бы сделать:
Foo foo = ReflectiveBuilder.from(Foo.class).
set("id", 1).
set("title", "title").
build();
Это имеет три массовые проблемы:
- поля являются
String
s - опечатка приводит к ошибке во время выполнения, а не компиляции одного ,
- значения
Object
s - неправильный тип вызывает ошибку времени выполнения, а не время компиляции, и
- было бы намного медленнее, чем альтернатива, так как отражение очень медленное.
Таким образом, решение на основе отражения, хотя и возможно (см. Apache Commons BeanUtils BeanMap
), совсем не практично.
Долгий ответ, если вы готовы разрешить некоторые магии времени компиляции, вы можете использовать Project Lombok. Идея Lombok заключается в создании кода шаблона из аннотаций с использованием препроцессора аннотации Java.
Действительно волшебная вещь заключается в том, что все IDE, а также большие 3, по крайней мере, понимают, что предварительная обработка аннотаций и завершение кода будут функционировать корректно, даже если код не действительно существует.
В случае включения POJO
с Builder
вы можете использовать @Data
и @Builder
@Data
@Builder
public class Foo {
public int id;
public String title;
public boolean change;
...
}
@Data
аннотацию сгенерирует:
- необходимым аргументы конструктора (который принимает все
final
поля),
equals
и hashCode
методы, которые используют все поля (может быть сконфигурирован с @EqualsAndHashCode
аннотацию)
toString
метод на всех областях (могут быть сконфигурированы с @ToString
аннотацию и
public
методы получения и установки для всех полей (могут быть сконфигурированы с использованием @Getter
/@Setter
аннотации на полях).
@Builder
аннотации будут генерировать внутренний класс под названием Builder
, которые могут быть инстанцированным с помощью Foo.builder()
.
ли убедитесь, что вы настроить методы equals
, hashCode
и toString
, как если у вас есть два класса с Ломбками, которые имеют ссылки друг на друг, то вы будете в конечном итоге с бесконечным циклом в случае, если по умолчанию, как оба класса включает другие в эти методы.
Существует также новый configuration system, что позволяет использовать, например, текучие сеттер, так что вы можете более или менее покончите с застройщиком, если ваш POJO изменчив:
new Foo().setId(3).setTitle("title)...
Для другого подхода, можно посмотрите на Aspect-oriented programming (АОП) и AspectJ. AOP позволяет вам рубить ваши классы в «аспекты», а затем придерживаться их вместе с помощью определенных правил с использованием предварительного компилятора. Например, вы можете точно реализовать то, что делает Lombok, используя пользовательские аннотации и аспект. Однако это довольно сложная тема, и ее вполне можно переусердствовать.
Используете ли вы общие ресурсы Apache для hashCode toString и равно? Это все еще боль, но сэкономит вам много времени. У вас есть базовый класс, который рефлексивно делает toString, equals и hashCode, а затем выводит все ваши POJO из этого – Leon
@Leon. На самом деле. Но каждый класс по-прежнему будет составлять 70-100 строк кода от каждого строителя.Должна быть лучшая модель, о которой я просто не знаю, или способ реализовать отражающий строитель, по крайней мере, так я себя чувствую. – buildpattern