Kurze Antwort keine. Was du verlangst, ist nicht möglich. Reflection betrachtet den Code zur Laufzeit und ruft Methoden dynamisch auf, er kann keine tatsächlichen Methoden generieren.
Was könnten Sie wären tun:
Foo foo = ReflectiveBuilder.from(Foo.class).
set("id", 1).
set("title", "title").
build();
Dies hat drei massive Probleme:
- die Felder sind
String
s - ein Tippfehler verursacht einen Laufzeitfehler eher als eine Kompilierung einer ,
- Die Werte sind
Object
s - der falsche Typ verursacht einen Laufzeitfehler statt einer Kompilierzeit eins und
- wäre es viel langsamer als die Alternative, da Reflection sehr langsam ist.
So eine Reflektion basierte Lösung, während möglich (siehe Apache Commons BeanUtils BeanMap
) ist überhaupt nicht praktisch.
Lange Antwort, wenn Sie bereit sind, einige Kompilierzeit Magie erlauben, können Sie Project Lombok verwenden. Die Idee hinter Lombok ist die Generierung von Codebausteinen aus Annotationen mit dem Java Annotation Preprocessor System.Die wirklich magische Sache ist, dass alle IDEs, auch die großen 3 zumindest, die Annotation-Vorverarbeitung und die Code-Vervollständigung funktionieren, auch wenn der Code nicht existiert wirklich.
Im Fall eines POJO
mit einem Builder
Sie @Data
und @Builder
@Data
@Builder
public class Foo {
public int id;
public String title;
public boolean change;
...
}
Die @Data
Annotation erzeugen können:
- ein erforderliches Argument Konstruktor (das trifft alle
final
Felder),
equals
und hashCode
Methoden, die alle Felder verwenden (kann mit der @EqualsAndHashCode
Annotation)
- ein
toString
Verfahren auf allen Gebieten konfiguriert werden (mit der Anmerkung und @ToString
public
Getter und Setter für alle Felder konfiguriert werden (unter Verwendung der @Getter
/@Setter
Annotationen auf Feldern konfiguriert werden).
Die @Builder
Anmerkung wird eine innere Klasse erzeugt Builder
genannt, die unter Verwendung von Foo.builder()
instanziiert werden kann.
Sie sicherstellen, dass Sie konfigurieren die equals
, hashCode
und toString
Methoden, als ob Sie zwei Klassen mit Lombok haben, die Verweise auf einander haben, dann werden Sie mit einer Endlosschleife im Standardfall am Ende, da beide Klassen die anderen sind in diese Methoden.
Es gibt auch eine neue configuration system, die Sie zum Beispiel fließend Setter verwenden können, so dass Sie mehr oder weniger mit dem Erbauer zu tun, weg, wenn Ihr POJO wandelbar ist:
new Foo().setId(3).setTitle("title)...
Für einen anderen Ansatz können Sie Schauen Sie sich Aspect-oriented programming (AOP) und AspectJ an. AOP erlaubt es Ihnen, Ihre Klassen in "Aspekte" zu zerlegen und sie dann unter Verwendung bestimmter Regeln unter Verwendung eines Pre-Compilers zusammen zu kleben. Zum Beispiel könnten Sie genau das umsetzen, was Lombok tut, indem Sie benutzerdefinierte Anmerkungen und einen Aspekt verwenden. Dies ist jedoch ein ziemlich fortgeschrittenes Thema und könnte durchaus übertrieben sein.
Verwenden Sie Apache commons für toString hashCode und gleich? Es ist immer noch ein Schmerz, aber sparen Sie eine Menge Zeit. Sie Code haben eine Basisklasse, die reflectively toString, equals und hashCode dann alle Ihre POJOs aus diesem – Leon
@Leon ich tatsächlich ableiten. Aber jede Klasse wird immer noch 70-100 Codezeilen von jedem Builder haben.Es muss ein besseres Muster geben, das mir nicht bewusst ist, oder ein Weg, einen reflektierenden Baumeister zu implementieren, zumindest fühle ich mich so. – buildpattern