Code generating beans in Java

Stephen Colebourne
Stephen ColebourneEngineering Lead at OpenGamma
Bean generation
Stop writing getters and setters
Stephen Colebourne, @jodastephen
Engineering Lead, OpenGamma
September 2016
http://blog.joda.org
Stephen Colebourne
● Java Champion, regular conference speaker
● Best known for date & time - Joda-Time and JSR-310
● More Joda projects - http://www.joda.org
● Major contributions in Apache Commons
● Blog - http://blog.joda.org
● Worked at OpenGamma for 6 years
Strata, from OpenGamma
● Open Source market risk library
● Valuation and risk calcs for finance
○ interest rate swap, FRA, CDS
● Great example of Java SE 8 coding style
http://strata.opengamma.io/
Introduction
⇒
Why use beans?
● Beans are used in most applications
● Common denominator between applications & libraries
● ORMs (Hibernate, JPA, etc.)
● Serialization (Binary, JSON, XML, etc.)
● Mappers/configuration (Spring, Dozer, etc.)
What is a bean?
● JavaBean specification v1.01, from 1997
● Focus on software components, COM/DCOM
● Manipulated visually in GUIs
● Java components within MS Word/Excel !!!
● References to floppy disks !!!
What is a bean?
● JavaBeans must extend java.awt.Component
● Created via standard factories
● No use of casts of instanceof checks
● Checked exceptions, not unchecked
● Communication via events
● Very specific rules around capitalization
● Use of BeanInfo and PropertyEditor
What is a bean?
"Bean" != JavaBean
What is a mutable bean?
● Each tool has subtly different definition
● Most agree on
○ no-args constructor
○ getters match getXxx()
○ setters match setXxx()
○ equals() / hashCode() / toString()
// Java 7
List<Person> people = loadPeople();
Collections.sort(people, new Comparator<Person>() {
@Override
public int compare(Person p1, Person p2) {
return p1.name.compareTo(p2.name);
}
});
Pattern for mutable bean
/** Represents a person. */
public class Person {
/** The forename of the person. */
private String forename;
/** The surname of the person. */
private String surname;
/** The birth date of the person. */
private LocalDate birthDate;
// Java 7
List<Person> people = loadPeople();
Collections.sort(people, new Comparator<Person>() {
@Override
public int compare(Person p1, Person p2) {
return p1.name.compareTo(p2.name);
}
});
Pattern for mutable bean
/** Creates an empty instance of Person. */
public Person() {}
/** Gets the forename of the person. */
public String getForename() { … }
/** Sets the forename of the person. */
public void setForename(String forename) { … }
// same for surname/birthDate
// Java 7
List<Person> people = loadPeople();
Collections.sort(people, new Comparator<Person>() {
@Override
public int compare(Person p1, Person p2) {
return p1.name.compareTo(p2.name);
}
});
Pattern for mutable bean
/** Compares this person to another. */
public boolean equals(Object obj) { … }
/** Returns a suitable hash code. */
public int hashCode() { … }
/** Returns a string summary of this object. */
public String toString() { … }
What is an immutable bean?
● "Beans" has traditionally implied mutability
● Many tools can't handle immutable beans
● No setters, may have "withers"
● Class must be final, with final fields
● Factory or builder instead of constructor
Why immutable?
● Thread-safe
● Java Memory Model guarantees
● No need to trust other methods not to modify
● State checked and valid on construction
● Nulls can be eliminated
// Java 7
List<Person> people = loadPeople();
Collections.sort(people, new Comparator<Person>() {
@Override
public int compare(Person p1, Person p2) {
return p1.name.compareTo(p2.name);
}
});
Pattern for immutable bean
/** Represents a person. */
public final class Person {
/** The forename of the person. */
private final String forename;
/** The surname of the person. */
private final String surname;
/** The birth date of the person. */
private final LocalDate birthDate;
// Java 7
List<Person> people = loadPeople();
Collections.sort(people, new Comparator<Person>() {
@Override
public int compare(Person p1, Person p2) {
return p1.name.compareTo(p2.name);
}
});
Pattern for immutable bean
/** Obtains an instance of Person. */
public Person of(
String surname, String forename, LocalDate date) { … }
/** Gets the forename of the person. */
public String getForename() { … }
/** Returns a copy with the specified forename. */
public Person withForename(String forename) { … }
// same for surname/birthDate
// Java 7
List<Person> people = loadPeople();
Collections.sort(people, new Comparator<Person>() {
@Override
public int compare(Person p1, Person p2) {
return p1.name.compareTo(p2.name);
}
});
Pattern for immutable bean
/** Compares this person to another. */
public boolean equals(Object obj) { … }
/** Returns a suitable hash code. */
public int hashCode() { … }
/** Returns a string summary of this object. */
public String toString() { … }
Pattern for immutable bean
● May prefer to have a builder instead of a factory
// factory
Person person = Person.of("Stephen", "Colebourne", date);
// or builder
Person person = Person.builder()
.forename("Stephen")
.surname("Colebourne")
.birthDate(date)
.build();
What is a VALJO?
● POJO - Plain Old Java Object
● VALJO - Value Java Object
○ http://blog.joda.org/2014/03/valjos-value-java-objects.html
● No use of identity - equal is interchangeable
● Immutable bean with extra restrictions
○ may be suitable for conversion to value types in Java 10/11
○ logical state clearly defined and used in equals()/hashCode()
○ comparable consistent with equals()
○ constructor must be private
○ formal string representation that can be parsed
Creating beans
How to create beans
● Lots of different ways to create beans
● Best option depends on use case
● Mutable vs Immutable
Option 1 - Manual
● Write each bean manually
● Deathly boring
● Double deathly boring for immutable beans
● Error-prone
● Probably not tested or code reviewed
Option 2 - Another JVM language
● Kotlin code much shorter
// Kotlin immutable bean
data class Person(
val forename: String,
val surname: String,
val birthDate: LocalDate)
Option 2 - Another JVM language
● Groovy code much shorter
// Groovy mutable bean
class Customer {
String forename
String surname
LocalDate birthDate
Option 3 - Language change
● New language feature in Java
● Perhaps like Kotlin/Groovy
● Doesn't help us now
● Likely to be restrictive
Option 4 - IDE generation
● Eclipse / IntelliJ / NetBeans can generate the code
○ Eclipse uses Ctrl+Alt+S followed by R / O / H / S
○ IntelliJ uses Alt+Insert
● One time generation, doesn't handle change
● Can you express field is not null?
● Can you generate immutable builders?
● Still not tested or code reviewed
Option 5 - Use a tool
● AutoValue
● Immutables
● Lombok
● Joda-Beans
● (VALJOGen)
● (POJOmatic)
AutoValue
AutoValue
● Annotation processor
● Open Source, from Google
○ https://github.com/google/auto/tree/master/value
Annotation processing
● Additional step during compilation
● Compiler calls annotation processor
● Processor generates additional files
● If generated file is a .java file then it is compiled
Annotation processing
Person
(abstract)
PersonImpl
(concrete)
Compilation finds
annotations and
code generates
You write
abstract class
Annotation processing
● Maven
○ just add the dependency
● Eclipse with Maven
○ install m2e-apt plugin
○ turn it on in the preferences
● IntelliJ with Maven
○ turn it on in the preferences
// Java 7
List<Person> people = loadPeople();
Collections.sort(people, new Comparator<Person>() {
@Override
public int compare(Person p1, Person p2) {
return p1.name.compareTo(p2.name);
}
});
AutoValue: your code
@AutoValue
public abstract class Person {
public static Person of(String name, LocalDate date) {
return new AutoValue_Person(name, date);
}
public abstract String getName();
public abstract LocalDate getBirthDate();
}
// Java 7
List<Person> people = loadPeople();
Collections.sort(people, new Comparator<Person>() {
@Override
public int compare(Person p1, Person p2) {
return p1.name.compareTo(p2.name);
}
});
AutoValue: generated
@Generated("com.google.auto.value.processor.AutoValueProcessor")
final class AutoValue_Person extends Person {
private final String name;
private final LocalDate birthDate;
// constructor, getters, equals, hashCode, toString
// Java 7
List<Person> people = loadPeople();
Collections.sort(people, new Comparator<Person>() {
@Override
public int compare(Person p1, Person p2) {
return p1.name.compareTo(p2.name);
}
});
AutoValue builder: your code
@AutoValue
public abstract class Person {
public static Builder builder() {
return new AutoValue_Person.Builder();
}
@AutoValue.Builder
public static abstract class Builder {
public abstract Builder name(String name);
public abstract Builder birthDate(LocalDate date);
public abstract Person build();
}
public abstract Builder toBuilder();
AutoValue options
● Handles name() or getName() convention
● Can override (underride) equals/hashCode/toString
● Can add any other method
● Can change fields to nullable using @Nullable
● Supports memoized fields
● Builder can have sub-builders for collections
● Pattern to handle builder validation
● Extensions API, but undocumented
AutoValue pros/cons
● Callers use Person like a normal bean
○ but they can see class is abstract
● Generated code is package scoped
○ you must write outline builder and/or static factory method
○ quite a lot of code still to write
● Simple, does sensible thing for most use cases
○ not that many options
● Only for immutable beans
Immutables
Immutables
● Annotation processor
● Open Source
○ https://immutables.github.io/
● Reacts to use Guava if available
// Java 7
List<Person> people = loadPeople();
Collections.sort(people, new Comparator<Person>() {
@Override
public int compare(Person p1, Person p2) {
return p1.name.compareTo(p2.name);
}
});
Immutables: your code
@Value.Immutable
public interface Person {
String getName();
LocalDate getBirthDate();
}
// Java 7
List<Person> people = loadPeople();
Collections.sort(people, new Comparator<Person>() {
@Override
public int compare(Person p1, Person p2) {
return p1.name.compareTo(p2.name);
}
});
Immutables: generated
@SuppressWarnings("all")
@Generated({"Immutables.generator", "ImmutablePerson"})
public final class ImmutablePerson implements Person {
private final String name;
private final LocalDate birthDate;
private ImmutablePerson(String name, LocalDate birthDate) {
this.name = name;
this.birthDate = birthDate;
}
// getters, withers, equals, hashCode, toString, builder
Immutables options
● Can generate from abstract class or interface
● Handles name() or getName() convention
● Can override (underride) equals/hashCode/toString
● Can add any other method
● Pre-computed hash code
● Instance interning
● and lots more!
// Java 7
List<Person> people = loadPeople();
Collections.sort(people, new Comparator<Person>() {
@Override
public int compare(Person p1, Person p2) {
return p1.name.compareTo(p2.name);
}
});
Immutables: hide implementation
@Value.Immutable
@Value.Style(visibility = PACKAGE)
public abstract class Person extends WithPerson {
public String getName();
public LocalDate getBirthDate();
public static class Builder
implements ImmutablePerson.Builder {}
}
Immutables pros/cons
● Many options and ways to generate
○ takes time to choose best option
● Callers see and use generated class (by default)
○ hiding generated class possible if you write more code
● Mutable beans supported
○ more like builders, do not follow JavaBeans spec
Lombok
Lombok
● Internal APIs
● Open Source
○ https://projectlombok.org/
● Uses agents and annotation processors
● Works best with Eclipse, but requires installing
// Java 7
List<Person> people = loadPeople();
Collections.sort(people, new Comparator<Person>() {
@Override
public int compare(Person p1, Person p2) {
return p1.name.compareTo(p2.name);
}
});
Lombok: your code - mutable
@Data
public class Person {
private String name;
private LocalDate birthDate;
}
// Java 7
List<Person> people = loadPeople();
Collections.sort(people, new Comparator<Person>() {
@Override
public int compare(Person p1, Person p2) {
return p1.name.compareTo(p2.name);
}
});
Lombok: generated- mutable
@Data
public class Person {
private String name;
private LocalDate birthDate;
// constructor, getters, setters, equals, hashCode, toString
}
// Java 7
List<Person> people = loadPeople();
Collections.sort(people, new Comparator<Person>() {
@Override
public int compare(Person p1, Person p2) {
return p1.name.compareTo(p2.name);
}
});
Lombok: your code - immutable
@Value
public class Person {
private String name;
private LocalDate birthDate;
}
// Java 7
List<Person> people = loadPeople();
Collections.sort(people, new Comparator<Person>() {
@Override
public int compare(Person p1, Person p2) {
return p1.name.compareTo(p2.name);
}
});
Lombok: generated - immutable
@Value
public final class Person {
private final String name;
private final LocalDate birthDate;
// constructor, getters, equals, hashCode, toString, builder
}
Lombok options
● Over 15 annotations and tweaks
● Use other annotations for more control
● Can add any other method
Lombok pros/cons
● No second class, proper immutable bean
○ resulting bean is exactly the same as manually written
● Works best with Maven and Eclipse
○ installation in Eclipse not via a standard plugin
● Uses internal API hackery
○ higher risk option
● Generated code is invisible
○ cannot step in when debugging
○ can "delombok" to code generated code
Joda-Beans
Joda-Beans
● Same-file regenerator
● Open Source, by me @jodastephen
○ http://www.joda.org/joda-beans/
● Adds autogenerated block to your code
● Generation using Maven/Gradle, on-save in Eclipse
// Java 7
List<Person> people = loadPeople();
Collections.sort(people, new Comparator<Person>() {
@Override
public int compare(Person p1, Person p2) {
return p1.name.compareTo(p2.name);
}
});
Joda-Beans: your code - mutable
@BeanDefinition
public class Person implements Bean {
@PropertyDefinition
private String name;
@PropertyDefinition
private LocalDate birthDate;
}
// Java 7
List<Person> people = loadPeople();
Collections.sort(people, new Comparator<Person>() {
@Override
public int compare(Person p1, Person p2) {
return p1.name.compareTo(p2.name);
}
});
Joda-Beans: generated - mutable
@BeanDefinition
public class Person implements Bean {
@PropertyDefinition
private String name;
@PropertyDefinition
private LocalDate birthDate;
// ---- AUTOGENERATED START ----
// getters, setters, equals, hashCode, toString, properties
// ----- AUTOGENERATED END -----
}
Properties
● C# and most other languages have properties
● Higher level than a field
● Bean is a set of properties
● Can list, get and set properties
○ like reflection
● Very useful abstraction for frameworks
Joda-Beans properties
● Bean provides abstraction for properties
● MetaBean acts like Class
● Can loop over MetaProperty for each property
○ meta bean acts as a hash-map of property name to property
○ no reflection
● BeanBuilder allows a bean to be created
○ this allows immutable beans to be created one property at a time
// Java 7
List<Person> people = loadPeople();
Collections.sort(people, new Comparator<Person>() {
@Override
public int compare(Person p1, Person p2) {
return p1.name.compareTo(p2.name);
}
});
Joda-Beans: your code immutable
@BeanDefinition
public class Person implements ImmutableBean {
@PropertyDefinition(validate = "notNull")
private String name;
@PropertyDefinition(validate = "notNull")
private LocalDate birthDate;
}
// Java 7
List<Person> people = loadPeople();
Collections.sort(people, new Comparator<Person>() {
@Override
public int compare(Person p1, Person p2) {
return p1.name.compareTo(p2.name);
}
});
Joda-Beans: generated immutable
@BeanDefinition
public class Person implements ImmutableBean {
@PropertyDefinition(validate = "notNull")
private String name;
@PropertyDefinition(validate = "notNull")
private LocalDate birthDate;
// ---- AUTOGENERATED START ----
// getters, equals, hashCode, toString, properties, builder
// ----- AUTOGENERATED END -----
}
Joda-Beans options
● Annotations allow field-level and bean-level control
● Control scope/style for getters/setters
● Supports pragmatic optional usage
● Can add any validation code
● Defaults/cross-validation for immutable bean builders
● Can default one property from another in builder
● Can fully override constructor
Joda-Beans pros/cons
● No second class, proper immutable bean
○ resulting bean is same as manually written
● Adds abstraction for properties without reflection
○ key reason to use Joda-Beans, but requires runtime dependency
● Built in XML, JSON, Binary serialization
● Generated code is visible for debugging
○ more code to checkin, but easy to ignore in review
○ proper Javadoc
● Plugin for Maven, Gradle and Eclipse with M2E
○ anyone want to volunteer to write an IntelliJ one?
Comparisons
Comparisons
● Annotation processor
○ AutoValue
○ Immutables
● Internal APIs
○ Lombok
● Same file regenerator
○ Joda-Beans
Comparisons
● All can generate a lot of useful code
○ getters, factories, builders, equals, hashCode, toString
● Some can generate mutable beans
● Only Joda-Beans generates C# style properties
● Each project has a different trade-off
Same class vs Generated class
● Same class (Joda-Beans, Lombok)
○ your code involves writing fields
○ caller sees concrete class
○ properly immutable
● Generated class (AutoValue, Immutables)
○ your code involves writing methods (more code)
○ caller sees abstract class or interface
○ is it really immutable?
○ IDE rename class typically breaks code
Collections
● Immutable beans should use Guava ImmutableList
● Builder needs to take List and convert internally
● All except Lombok do this correctly
Installation requirements
● AutoValue & Immutables use annotation processor
○ must be configured in IDE, extra plugin for Eclipse
● Lombok uses internal API hackery
○ requires specific Eclipse installation
● Joda-Beans runs as separate code regenerator
○ for Eclipse, just needs standard M2E
AutoValue vs Immutables
● AutoValue
○ you write abstract class
○ generated class is package-scoped
○ cannot generate static factory
○ must write builder outline manually
● Immutables
○ you write interface or abstract class
○ generated class is public (can be made private or package-scoped)
○ static factory and builder in generated class
○ lots of flexibility
Valid on checkout
● AutoValue, Immutables, Lombok
○ code invalid in IDE on checkout unless configured
○ only your code checked in
● Joda-Beans
○ code valid in IDE on checkout, even if not configured
○ your code and generated code checked in
Evaluate yourself
● GitHub project with everything setup for comparison
○ https://github.com/jodastephen/compare-beangen
● Includes 4 tools discussed
○ plus VALJOGen, POJOmatic, Eclipse wizards and IntelliJ wizards
● Good project to play with each tool
Summary
✯
Summary
● All four tools have their sweet spot and trade off
○ AutoValue - simplicity, abstract class
○ Immutables - comprehensive, abstract class or interface
○ Lombok - almost a language extension, hacky implementation
○ Joda-Beans - C# style properties, runtime dependency
Summary - personal view
● Use Joda-Beans if you like properties
○ Code should be valid on checkout
○ Immutable beans should be final
○ Want C# style properties
○ Hence I wrote and use Joda-Beans
● Otherwise, use Immutables
@jodastephen
http://blog.joda.org
1 of 74

Recommended

Functional Java 8 - Introduction by
Functional Java 8 - IntroductionFunctional Java 8 - Introduction
Functional Java 8 - IntroductionŁukasz Biały
637 views157 slides
Java 8 ​and ​Best Practices by
Java 8 ​and ​Best PracticesJava 8 ​and ​Best Practices
Java 8 ​and ​Best PracticesBuddhini Seneviratne
85 views92 slides
10 Sets of Best Practices for Java 8 by
10 Sets of Best Practices for Java 810 Sets of Best Practices for Java 8
10 Sets of Best Practices for Java 8Garth Gilmour
4.4K views85 slides
Java 8 by example! by
Java 8 by example!Java 8 by example!
Java 8 by example!Mark Harrison
352 views53 slides
Java SE 8 library design by
Java SE 8 library designJava SE 8 library design
Java SE 8 library designStephen Colebourne
3K views87 slides
Java SE 8 best practices by
Java SE 8 best practicesJava SE 8 best practices
Java SE 8 best practicesStephen Colebourne
100.8K views88 slides

More Related Content

What's hot

Java 8 presentation by
Java 8 presentationJava 8 presentation
Java 8 presentationVan Huong
6.1K views63 slides
Functional programming with Java 8 by
Functional programming with Java 8Functional programming with Java 8
Functional programming with Java 8LivePerson
6.9K views76 slides
Java best practices by
Java best practicesJava best practices
Java best practicesRay Toal
3.7K views47 slides
Lambda Chops - Recipes for Simpler, More Expressive Code by
Lambda Chops - Recipes for Simpler, More Expressive CodeLambda Chops - Recipes for Simpler, More Expressive Code
Lambda Chops - Recipes for Simpler, More Expressive CodeIan Robertson
602 views37 slides
Java 8 Lambda Expressions & Streams by
Java 8 Lambda Expressions & StreamsJava 8 Lambda Expressions & Streams
Java 8 Lambda Expressions & StreamsNewCircle Training
11.7K views90 slides
Java 8 features by
Java 8 featuresJava 8 features
Java 8 featuresNexThoughts Technologies
5.9K views69 slides

What's hot(20)

Java 8 presentation by Van Huong
Java 8 presentationJava 8 presentation
Java 8 presentation
Van Huong6.1K views
Functional programming with Java 8 by LivePerson
Functional programming with Java 8Functional programming with Java 8
Functional programming with Java 8
LivePerson6.9K views
Java best practices by Ray Toal
Java best practicesJava best practices
Java best practices
Ray Toal3.7K views
Lambda Chops - Recipes for Simpler, More Expressive Code by Ian Robertson
Lambda Chops - Recipes for Simpler, More Expressive CodeLambda Chops - Recipes for Simpler, More Expressive Code
Lambda Chops - Recipes for Simpler, More Expressive Code
Ian Robertson602 views
Productive Programming in Java 8 - with Lambdas and Streams by Ganesh Samarthyam
Productive Programming in Java 8 - with Lambdas and Streams Productive Programming in Java 8 - with Lambdas and Streams
Productive Programming in Java 8 - with Lambdas and Streams
Ganesh Samarthyam11.7K views
New Features in JDK 8 by Martin Toshev
New Features in JDK 8New Features in JDK 8
New Features in JDK 8
Martin Toshev19.2K views
Functional programming principles and Java 8 by Dragos Balan
Functional programming principles and Java 8Functional programming principles and Java 8
Functional programming principles and Java 8
Dragos Balan1.5K views
Introduction of Java 8 with emphasis on Lambda Expressions and Streams by Emiel Paasschens
Introduction of Java 8 with emphasis on Lambda Expressions and StreamsIntroduction of Java 8 with emphasis on Lambda Expressions and Streams
Introduction of Java 8 with emphasis on Lambda Expressions and Streams
Emiel Paasschens3K views
Java SE 9 modules - an introduction (July 2018) by Stephen Colebourne
Java SE 9 modules - an introduction (July 2018)Java SE 9 modules - an introduction (July 2018)
Java SE 9 modules - an introduction (July 2018)
Stephen Colebourne225 views
How Green are Java Best Coding Practices? - GreenDays @ Rennes - 2014-07-01 by Jérôme Rocheteau
How Green are Java Best Coding Practices? - GreenDays @ Rennes - 2014-07-01How Green are Java Best Coding Practices? - GreenDays @ Rennes - 2014-07-01
How Green are Java Best Coding Practices? - GreenDays @ Rennes - 2014-07-01
Jérôme Rocheteau1.1K views
New Features Of JDK 7 by Deniz Oguz
New Features Of JDK 7New Features Of JDK 7
New Features Of JDK 7
Deniz Oguz10.5K views
Lambda: A Peek Under The Hood - Brian Goetz by JAX London
Lambda: A Peek Under The Hood - Brian GoetzLambda: A Peek Under The Hood - Brian Goetz
Lambda: A Peek Under The Hood - Brian Goetz
JAX London8K views
Java Tutorial by Vijay A Raj
Java TutorialJava Tutorial
Java Tutorial
Vijay A Raj34.3K views

Viewers also liked

Java 8 date & time by
Java 8 date & timeJava 8 date & time
Java 8 date & timeOleg Tsal-Tsalko
1.7K views18 slides
Code Review Matters and Manners by
Code Review Matters and MannersCode Review Matters and Manners
Code Review Matters and MannersTrisha Gee
4K views46 slides
#NoXML: Eliminating XML in Spring Projects - SpringOne 2GX 2015 by
#NoXML: Eliminating XML in Spring Projects - SpringOne 2GX 2015#NoXML: Eliminating XML in Spring Projects - SpringOne 2GX 2015
#NoXML: Eliminating XML in Spring Projects - SpringOne 2GX 2015Matt Raible
37.4K views67 slides
Javabeans by
JavabeansJavabeans
Javabeansvamsitricks
4.2K views32 slides
Java beans by
Java beansJava beans
Java beanssptatslide
12.7K views14 slides
Electronic governance steps in the right direction? by
Electronic governance   steps in the right direction?Electronic governance   steps in the right direction?
Electronic governance steps in the right direction?Bozhidar Bozhanov
4.4K views27 slides

Viewers also liked(8)

Code Review Matters and Manners by Trisha Gee
Code Review Matters and MannersCode Review Matters and Manners
Code Review Matters and Manners
Trisha Gee4K views
#NoXML: Eliminating XML in Spring Projects - SpringOne 2GX 2015 by Matt Raible
#NoXML: Eliminating XML in Spring Projects - SpringOne 2GX 2015#NoXML: Eliminating XML in Spring Projects - SpringOne 2GX 2015
#NoXML: Eliminating XML in Spring Projects - SpringOne 2GX 2015
Matt Raible37.4K views
Java beans by sptatslide
Java beansJava beans
Java beans
sptatslide12.7K views
Electronic governance steps in the right direction? by Bozhidar Bozhanov
Electronic governance   steps in the right direction?Electronic governance   steps in the right direction?
Electronic governance steps in the right direction?
Bozhidar Bozhanov4.4K views
What is tackled in the Java EE Security API (Java EE 8) by Rudy De Busscher
What is tackled in the Java EE Security API (Java EE 8)What is tackled in the Java EE Security API (Java EE 8)
What is tackled in the Java EE Security API (Java EE 8)
Rudy De Busscher18.8K views
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin... by Matt Raible
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...
Matt Raible68.4K views

Similar to Code generating beans in Java

Code Generation with Groovy, Lombok, AutoValue and Immutables - Ted's Tool Time by
Code Generation with Groovy, Lombok, AutoValue and Immutables - Ted's Tool TimeCode Generation with Groovy, Lombok, AutoValue and Immutables - Ted's Tool Time
Code Generation with Groovy, Lombok, AutoValue and Immutables - Ted's Tool TimeTed Vinke
1.3K views18 slides
Android (software) Design Pattern by
Android (software) Design PatternAndroid (software) Design Pattern
Android (software) Design PatternArif Huda
1.6K views19 slides
Kotlin intro by
Kotlin introKotlin intro
Kotlin introElifarley Cruz
610 views38 slides
Having Fun with Kotlin Android - DILo Surabaya by
Having Fun with Kotlin Android - DILo SurabayaHaving Fun with Kotlin Android - DILo Surabaya
Having Fun with Kotlin Android - DILo SurabayaDILo Surabaya
1.3K views46 slides
AST Transformations by
AST TransformationsAST Transformations
AST TransformationsHamletDRC
1.2K views87 slides
AST Transformations at JFokus by
AST Transformations at JFokusAST Transformations at JFokus
AST Transformations at JFokusHamletDRC
945 views101 slides

Similar to Code generating beans in Java(20)

Code Generation with Groovy, Lombok, AutoValue and Immutables - Ted's Tool Time by Ted Vinke
Code Generation with Groovy, Lombok, AutoValue and Immutables - Ted's Tool TimeCode Generation with Groovy, Lombok, AutoValue and Immutables - Ted's Tool Time
Code Generation with Groovy, Lombok, AutoValue and Immutables - Ted's Tool Time
Ted Vinke1.3K views
Android (software) Design Pattern by Arif Huda
Android (software) Design PatternAndroid (software) Design Pattern
Android (software) Design Pattern
Arif Huda1.6K views
Having Fun with Kotlin Android - DILo Surabaya by DILo Surabaya
Having Fun with Kotlin Android - DILo SurabayaHaving Fun with Kotlin Android - DILo Surabaya
Having Fun with Kotlin Android - DILo Surabaya
DILo Surabaya1.3K views
AST Transformations by HamletDRC
AST TransformationsAST Transformations
AST Transformations
HamletDRC1.2K views
AST Transformations at JFokus by HamletDRC
AST Transformations at JFokusAST Transformations at JFokus
AST Transformations at JFokus
HamletDRC945 views
Apache Groovy: the language and the ecosystem by Kostas Saidis
Apache Groovy: the language and the ecosystemApache Groovy: the language and the ecosystem
Apache Groovy: the language and the ecosystem
Kostas Saidis2.8K views
Writing code that writes code - Nguyen Luong by Vu Huy
Writing code that writes code - Nguyen LuongWriting code that writes code - Nguyen Luong
Writing code that writes code - Nguyen Luong
Vu Huy270 views
TechkTalk #12 Grokking: Writing code that writes code – Nguyen Luong by Grokking VN
TechkTalk #12 Grokking: Writing code that writes code – Nguyen LuongTechkTalk #12 Grokking: Writing code that writes code – Nguyen Luong
TechkTalk #12 Grokking: Writing code that writes code – Nguyen Luong
Grokking VN1.2K views
運用Closure Compiler 打造高品質的JavaScript by taobao.com
運用Closure Compiler 打造高品質的JavaScript運用Closure Compiler 打造高品質的JavaScript
運用Closure Compiler 打造高品質的JavaScript
taobao.com383 views
Groovy And Grails JUG Sardegna by John Leach
Groovy And Grails JUG SardegnaGroovy And Grails JUG Sardegna
Groovy And Grails JUG Sardegna
John Leach863 views
CSE 110 - Lab 6 What this Lab Is About  Working wi.docx by faithxdunce63732
CSE 110 - Lab 6 What this Lab Is About  Working wi.docxCSE 110 - Lab 6 What this Lab Is About  Working wi.docx
CSE 110 - Lab 6 What this Lab Is About  Working wi.docx
2007 09 10 Fzi Training Groovy Grails V Ws by loffenauer
2007 09 10 Fzi Training Groovy Grails V Ws2007 09 10 Fzi Training Groovy Grails V Ws
2007 09 10 Fzi Training Groovy Grails V Ws
loffenauer1.3K views
Модерни езици за програмиране за JVM (2011) by Bozhidar Batsov
Модерни езици за програмиране за JVM (2011)Модерни езици за програмиране за JVM (2011)
Модерни езици за програмиране за JVM (2011)
Bozhidar Batsov554 views
Bologna Developer Zone - About Kotlin by Marco Vasapollo
Bologna Developer Zone - About KotlinBologna Developer Zone - About Kotlin
Bologna Developer Zone - About Kotlin
Marco Vasapollo342 views

Recently uploaded

Copilot Prompting Toolkit_All Resources.pdf by
Copilot Prompting Toolkit_All Resources.pdfCopilot Prompting Toolkit_All Resources.pdf
Copilot Prompting Toolkit_All Resources.pdfRiccardo Zamana
16 views4 slides
The Era of Large Language Models.pptx by
The Era of Large Language Models.pptxThe Era of Large Language Models.pptx
The Era of Large Language Models.pptxAbdulVahedShaik
7 views9 slides
.NET Developer Conference 2023 - .NET Microservices mit Dapr – zu viel Abstra... by
.NET Developer Conference 2023 - .NET Microservices mit Dapr – zu viel Abstra....NET Developer Conference 2023 - .NET Microservices mit Dapr – zu viel Abstra...
.NET Developer Conference 2023 - .NET Microservices mit Dapr – zu viel Abstra...Marc Müller
41 views62 slides
Fleet Management Software in India by
Fleet Management Software in India Fleet Management Software in India
Fleet Management Software in India Fleetable
12 views1 slide
SAP FOR TYRE INDUSTRY.pdf by
SAP FOR TYRE INDUSTRY.pdfSAP FOR TYRE INDUSTRY.pdf
SAP FOR TYRE INDUSTRY.pdfVirendra Rai, PMP
28 views3 slides
HarshithAkkapelli_Presentation.pdf by
HarshithAkkapelli_Presentation.pdfHarshithAkkapelli_Presentation.pdf
HarshithAkkapelli_Presentation.pdfharshithakkapelli
12 views16 slides

Recently uploaded(20)

Copilot Prompting Toolkit_All Resources.pdf by Riccardo Zamana
Copilot Prompting Toolkit_All Resources.pdfCopilot Prompting Toolkit_All Resources.pdf
Copilot Prompting Toolkit_All Resources.pdf
Riccardo Zamana16 views
.NET Developer Conference 2023 - .NET Microservices mit Dapr – zu viel Abstra... by Marc Müller
.NET Developer Conference 2023 - .NET Microservices mit Dapr – zu viel Abstra....NET Developer Conference 2023 - .NET Microservices mit Dapr – zu viel Abstra...
.NET Developer Conference 2023 - .NET Microservices mit Dapr – zu viel Abstra...
Marc Müller41 views
Fleet Management Software in India by Fleetable
Fleet Management Software in India Fleet Management Software in India
Fleet Management Software in India
Fleetable12 views
predicting-m3-devopsconMunich-2023-v2.pptx by Tier1 app
predicting-m3-devopsconMunich-2023-v2.pptxpredicting-m3-devopsconMunich-2023-v2.pptx
predicting-m3-devopsconMunich-2023-v2.pptx
Tier1 app9 views
Bootstrapping vs Venture Capital.pptx by Zeljko Svedic
Bootstrapping vs Venture Capital.pptxBootstrapping vs Venture Capital.pptx
Bootstrapping vs Venture Capital.pptx
Zeljko Svedic14 views
20231129 - Platform @ localhost 2023 - Application-driven infrastructure with... by sparkfabrik
20231129 - Platform @ localhost 2023 - Application-driven infrastructure with...20231129 - Platform @ localhost 2023 - Application-driven infrastructure with...
20231129 - Platform @ localhost 2023 - Application-driven infrastructure with...
sparkfabrik8 views
Team Transformation Tactics for Holistic Testing and Quality (Japan Symposium... by Lisi Hocke
Team Transformation Tactics for Holistic Testing and Quality (Japan Symposium...Team Transformation Tactics for Holistic Testing and Quality (Japan Symposium...
Team Transformation Tactics for Holistic Testing and Quality (Japan Symposium...
Lisi Hocke35 views
Unlocking the Power of AI in Product Management - A Comprehensive Guide for P... by NimaTorabi2
Unlocking the Power of AI in Product Management - A Comprehensive Guide for P...Unlocking the Power of AI in Product Management - A Comprehensive Guide for P...
Unlocking the Power of AI in Product Management - A Comprehensive Guide for P...
NimaTorabi215 views
2023-November-Schneider Electric-Meetup-BCN Admin Group.pptx by animuscrm
2023-November-Schneider Electric-Meetup-BCN Admin Group.pptx2023-November-Schneider Electric-Meetup-BCN Admin Group.pptx
2023-November-Schneider Electric-Meetup-BCN Admin Group.pptx
animuscrm15 views
Dev-Cloud Conference 2023 - Continuous Deployment Showdown: Traditionelles CI... by Marc Müller
Dev-Cloud Conference 2023 - Continuous Deployment Showdown: Traditionelles CI...Dev-Cloud Conference 2023 - Continuous Deployment Showdown: Traditionelles CI...
Dev-Cloud Conference 2023 - Continuous Deployment Showdown: Traditionelles CI...
Marc Müller42 views
DRYiCE™ iAutomate: AI-enhanced Intelligent Runbook Automation by HCLSoftware
DRYiCE™ iAutomate: AI-enhanced Intelligent Runbook AutomationDRYiCE™ iAutomate: AI-enhanced Intelligent Runbook Automation
DRYiCE™ iAutomate: AI-enhanced Intelligent Runbook Automation
HCLSoftware6 views
Ports-and-Adapters Architecture for Embedded HMI by Burkhard Stubert
Ports-and-Adapters Architecture for Embedded HMIPorts-and-Adapters Architecture for Embedded HMI
Ports-and-Adapters Architecture for Embedded HMI
Burkhard Stubert26 views
AI and Ml presentation .pptx by FayazAli87
AI and Ml presentation .pptxAI and Ml presentation .pptx
AI and Ml presentation .pptx
FayazAli8713 views

Code generating beans in Java

  • 1. Bean generation Stop writing getters and setters Stephen Colebourne, @jodastephen Engineering Lead, OpenGamma September 2016 http://blog.joda.org
  • 2. Stephen Colebourne ● Java Champion, regular conference speaker ● Best known for date & time - Joda-Time and JSR-310 ● More Joda projects - http://www.joda.org ● Major contributions in Apache Commons ● Blog - http://blog.joda.org ● Worked at OpenGamma for 6 years
  • 3. Strata, from OpenGamma ● Open Source market risk library ● Valuation and risk calcs for finance ○ interest rate swap, FRA, CDS ● Great example of Java SE 8 coding style http://strata.opengamma.io/
  • 5. Why use beans? ● Beans are used in most applications ● Common denominator between applications & libraries ● ORMs (Hibernate, JPA, etc.) ● Serialization (Binary, JSON, XML, etc.) ● Mappers/configuration (Spring, Dozer, etc.)
  • 6. What is a bean? ● JavaBean specification v1.01, from 1997 ● Focus on software components, COM/DCOM ● Manipulated visually in GUIs ● Java components within MS Word/Excel !!! ● References to floppy disks !!!
  • 7. What is a bean? ● JavaBeans must extend java.awt.Component ● Created via standard factories ● No use of casts of instanceof checks ● Checked exceptions, not unchecked ● Communication via events ● Very specific rules around capitalization ● Use of BeanInfo and PropertyEditor
  • 8. What is a bean? "Bean" != JavaBean
  • 9. What is a mutable bean? ● Each tool has subtly different definition ● Most agree on ○ no-args constructor ○ getters match getXxx() ○ setters match setXxx() ○ equals() / hashCode() / toString()
  • 10. // Java 7 List<Person> people = loadPeople(); Collections.sort(people, new Comparator<Person>() { @Override public int compare(Person p1, Person p2) { return p1.name.compareTo(p2.name); } }); Pattern for mutable bean /** Represents a person. */ public class Person { /** The forename of the person. */ private String forename; /** The surname of the person. */ private String surname; /** The birth date of the person. */ private LocalDate birthDate;
  • 11. // Java 7 List<Person> people = loadPeople(); Collections.sort(people, new Comparator<Person>() { @Override public int compare(Person p1, Person p2) { return p1.name.compareTo(p2.name); } }); Pattern for mutable bean /** Creates an empty instance of Person. */ public Person() {} /** Gets the forename of the person. */ public String getForename() { … } /** Sets the forename of the person. */ public void setForename(String forename) { … } // same for surname/birthDate
  • 12. // Java 7 List<Person> people = loadPeople(); Collections.sort(people, new Comparator<Person>() { @Override public int compare(Person p1, Person p2) { return p1.name.compareTo(p2.name); } }); Pattern for mutable bean /** Compares this person to another. */ public boolean equals(Object obj) { … } /** Returns a suitable hash code. */ public int hashCode() { … } /** Returns a string summary of this object. */ public String toString() { … }
  • 13. What is an immutable bean? ● "Beans" has traditionally implied mutability ● Many tools can't handle immutable beans ● No setters, may have "withers" ● Class must be final, with final fields ● Factory or builder instead of constructor
  • 14. Why immutable? ● Thread-safe ● Java Memory Model guarantees ● No need to trust other methods not to modify ● State checked and valid on construction ● Nulls can be eliminated
  • 15. // Java 7 List<Person> people = loadPeople(); Collections.sort(people, new Comparator<Person>() { @Override public int compare(Person p1, Person p2) { return p1.name.compareTo(p2.name); } }); Pattern for immutable bean /** Represents a person. */ public final class Person { /** The forename of the person. */ private final String forename; /** The surname of the person. */ private final String surname; /** The birth date of the person. */ private final LocalDate birthDate;
  • 16. // Java 7 List<Person> people = loadPeople(); Collections.sort(people, new Comparator<Person>() { @Override public int compare(Person p1, Person p2) { return p1.name.compareTo(p2.name); } }); Pattern for immutable bean /** Obtains an instance of Person. */ public Person of( String surname, String forename, LocalDate date) { … } /** Gets the forename of the person. */ public String getForename() { … } /** Returns a copy with the specified forename. */ public Person withForename(String forename) { … } // same for surname/birthDate
  • 17. // Java 7 List<Person> people = loadPeople(); Collections.sort(people, new Comparator<Person>() { @Override public int compare(Person p1, Person p2) { return p1.name.compareTo(p2.name); } }); Pattern for immutable bean /** Compares this person to another. */ public boolean equals(Object obj) { … } /** Returns a suitable hash code. */ public int hashCode() { … } /** Returns a string summary of this object. */ public String toString() { … }
  • 18. Pattern for immutable bean ● May prefer to have a builder instead of a factory // factory Person person = Person.of("Stephen", "Colebourne", date); // or builder Person person = Person.builder() .forename("Stephen") .surname("Colebourne") .birthDate(date) .build();
  • 19. What is a VALJO? ● POJO - Plain Old Java Object ● VALJO - Value Java Object ○ http://blog.joda.org/2014/03/valjos-value-java-objects.html ● No use of identity - equal is interchangeable ● Immutable bean with extra restrictions ○ may be suitable for conversion to value types in Java 10/11 ○ logical state clearly defined and used in equals()/hashCode() ○ comparable consistent with equals() ○ constructor must be private ○ formal string representation that can be parsed
  • 21. How to create beans ● Lots of different ways to create beans ● Best option depends on use case ● Mutable vs Immutable
  • 22. Option 1 - Manual ● Write each bean manually ● Deathly boring ● Double deathly boring for immutable beans ● Error-prone ● Probably not tested or code reviewed
  • 23. Option 2 - Another JVM language ● Kotlin code much shorter // Kotlin immutable bean data class Person( val forename: String, val surname: String, val birthDate: LocalDate)
  • 24. Option 2 - Another JVM language ● Groovy code much shorter // Groovy mutable bean class Customer { String forename String surname LocalDate birthDate
  • 25. Option 3 - Language change ● New language feature in Java ● Perhaps like Kotlin/Groovy ● Doesn't help us now ● Likely to be restrictive
  • 26. Option 4 - IDE generation ● Eclipse / IntelliJ / NetBeans can generate the code ○ Eclipse uses Ctrl+Alt+S followed by R / O / H / S ○ IntelliJ uses Alt+Insert ● One time generation, doesn't handle change ● Can you express field is not null? ● Can you generate immutable builders? ● Still not tested or code reviewed
  • 27. Option 5 - Use a tool ● AutoValue ● Immutables ● Lombok ● Joda-Beans ● (VALJOGen) ● (POJOmatic)
  • 29. AutoValue ● Annotation processor ● Open Source, from Google ○ https://github.com/google/auto/tree/master/value
  • 30. Annotation processing ● Additional step during compilation ● Compiler calls annotation processor ● Processor generates additional files ● If generated file is a .java file then it is compiled
  • 32. Annotation processing ● Maven ○ just add the dependency ● Eclipse with Maven ○ install m2e-apt plugin ○ turn it on in the preferences ● IntelliJ with Maven ○ turn it on in the preferences
  • 33. // Java 7 List<Person> people = loadPeople(); Collections.sort(people, new Comparator<Person>() { @Override public int compare(Person p1, Person p2) { return p1.name.compareTo(p2.name); } }); AutoValue: your code @AutoValue public abstract class Person { public static Person of(String name, LocalDate date) { return new AutoValue_Person(name, date); } public abstract String getName(); public abstract LocalDate getBirthDate(); }
  • 34. // Java 7 List<Person> people = loadPeople(); Collections.sort(people, new Comparator<Person>() { @Override public int compare(Person p1, Person p2) { return p1.name.compareTo(p2.name); } }); AutoValue: generated @Generated("com.google.auto.value.processor.AutoValueProcessor") final class AutoValue_Person extends Person { private final String name; private final LocalDate birthDate; // constructor, getters, equals, hashCode, toString
  • 35. // Java 7 List<Person> people = loadPeople(); Collections.sort(people, new Comparator<Person>() { @Override public int compare(Person p1, Person p2) { return p1.name.compareTo(p2.name); } }); AutoValue builder: your code @AutoValue public abstract class Person { public static Builder builder() { return new AutoValue_Person.Builder(); } @AutoValue.Builder public static abstract class Builder { public abstract Builder name(String name); public abstract Builder birthDate(LocalDate date); public abstract Person build(); } public abstract Builder toBuilder();
  • 36. AutoValue options ● Handles name() or getName() convention ● Can override (underride) equals/hashCode/toString ● Can add any other method ● Can change fields to nullable using @Nullable ● Supports memoized fields ● Builder can have sub-builders for collections ● Pattern to handle builder validation ● Extensions API, but undocumented
  • 37. AutoValue pros/cons ● Callers use Person like a normal bean ○ but they can see class is abstract ● Generated code is package scoped ○ you must write outline builder and/or static factory method ○ quite a lot of code still to write ● Simple, does sensible thing for most use cases ○ not that many options ● Only for immutable beans
  • 39. Immutables ● Annotation processor ● Open Source ○ https://immutables.github.io/ ● Reacts to use Guava if available
  • 40. // Java 7 List<Person> people = loadPeople(); Collections.sort(people, new Comparator<Person>() { @Override public int compare(Person p1, Person p2) { return p1.name.compareTo(p2.name); } }); Immutables: your code @Value.Immutable public interface Person { String getName(); LocalDate getBirthDate(); }
  • 41. // Java 7 List<Person> people = loadPeople(); Collections.sort(people, new Comparator<Person>() { @Override public int compare(Person p1, Person p2) { return p1.name.compareTo(p2.name); } }); Immutables: generated @SuppressWarnings("all") @Generated({"Immutables.generator", "ImmutablePerson"}) public final class ImmutablePerson implements Person { private final String name; private final LocalDate birthDate; private ImmutablePerson(String name, LocalDate birthDate) { this.name = name; this.birthDate = birthDate; } // getters, withers, equals, hashCode, toString, builder
  • 42. Immutables options ● Can generate from abstract class or interface ● Handles name() or getName() convention ● Can override (underride) equals/hashCode/toString ● Can add any other method ● Pre-computed hash code ● Instance interning ● and lots more!
  • 43. // Java 7 List<Person> people = loadPeople(); Collections.sort(people, new Comparator<Person>() { @Override public int compare(Person p1, Person p2) { return p1.name.compareTo(p2.name); } }); Immutables: hide implementation @Value.Immutable @Value.Style(visibility = PACKAGE) public abstract class Person extends WithPerson { public String getName(); public LocalDate getBirthDate(); public static class Builder implements ImmutablePerson.Builder {} }
  • 44. Immutables pros/cons ● Many options and ways to generate ○ takes time to choose best option ● Callers see and use generated class (by default) ○ hiding generated class possible if you write more code ● Mutable beans supported ○ more like builders, do not follow JavaBeans spec
  • 46. Lombok ● Internal APIs ● Open Source ○ https://projectlombok.org/ ● Uses agents and annotation processors ● Works best with Eclipse, but requires installing
  • 47. // Java 7 List<Person> people = loadPeople(); Collections.sort(people, new Comparator<Person>() { @Override public int compare(Person p1, Person p2) { return p1.name.compareTo(p2.name); } }); Lombok: your code - mutable @Data public class Person { private String name; private LocalDate birthDate; }
  • 48. // Java 7 List<Person> people = loadPeople(); Collections.sort(people, new Comparator<Person>() { @Override public int compare(Person p1, Person p2) { return p1.name.compareTo(p2.name); } }); Lombok: generated- mutable @Data public class Person { private String name; private LocalDate birthDate; // constructor, getters, setters, equals, hashCode, toString }
  • 49. // Java 7 List<Person> people = loadPeople(); Collections.sort(people, new Comparator<Person>() { @Override public int compare(Person p1, Person p2) { return p1.name.compareTo(p2.name); } }); Lombok: your code - immutable @Value public class Person { private String name; private LocalDate birthDate; }
  • 50. // Java 7 List<Person> people = loadPeople(); Collections.sort(people, new Comparator<Person>() { @Override public int compare(Person p1, Person p2) { return p1.name.compareTo(p2.name); } }); Lombok: generated - immutable @Value public final class Person { private final String name; private final LocalDate birthDate; // constructor, getters, equals, hashCode, toString, builder }
  • 51. Lombok options ● Over 15 annotations and tweaks ● Use other annotations for more control ● Can add any other method
  • 52. Lombok pros/cons ● No second class, proper immutable bean ○ resulting bean is exactly the same as manually written ● Works best with Maven and Eclipse ○ installation in Eclipse not via a standard plugin ● Uses internal API hackery ○ higher risk option ● Generated code is invisible ○ cannot step in when debugging ○ can "delombok" to code generated code
  • 54. Joda-Beans ● Same-file regenerator ● Open Source, by me @jodastephen ○ http://www.joda.org/joda-beans/ ● Adds autogenerated block to your code ● Generation using Maven/Gradle, on-save in Eclipse
  • 55. // Java 7 List<Person> people = loadPeople(); Collections.sort(people, new Comparator<Person>() { @Override public int compare(Person p1, Person p2) { return p1.name.compareTo(p2.name); } }); Joda-Beans: your code - mutable @BeanDefinition public class Person implements Bean { @PropertyDefinition private String name; @PropertyDefinition private LocalDate birthDate; }
  • 56. // Java 7 List<Person> people = loadPeople(); Collections.sort(people, new Comparator<Person>() { @Override public int compare(Person p1, Person p2) { return p1.name.compareTo(p2.name); } }); Joda-Beans: generated - mutable @BeanDefinition public class Person implements Bean { @PropertyDefinition private String name; @PropertyDefinition private LocalDate birthDate; // ---- AUTOGENERATED START ---- // getters, setters, equals, hashCode, toString, properties // ----- AUTOGENERATED END ----- }
  • 57. Properties ● C# and most other languages have properties ● Higher level than a field ● Bean is a set of properties ● Can list, get and set properties ○ like reflection ● Very useful abstraction for frameworks
  • 58. Joda-Beans properties ● Bean provides abstraction for properties ● MetaBean acts like Class ● Can loop over MetaProperty for each property ○ meta bean acts as a hash-map of property name to property ○ no reflection ● BeanBuilder allows a bean to be created ○ this allows immutable beans to be created one property at a time
  • 59. // Java 7 List<Person> people = loadPeople(); Collections.sort(people, new Comparator<Person>() { @Override public int compare(Person p1, Person p2) { return p1.name.compareTo(p2.name); } }); Joda-Beans: your code immutable @BeanDefinition public class Person implements ImmutableBean { @PropertyDefinition(validate = "notNull") private String name; @PropertyDefinition(validate = "notNull") private LocalDate birthDate; }
  • 60. // Java 7 List<Person> people = loadPeople(); Collections.sort(people, new Comparator<Person>() { @Override public int compare(Person p1, Person p2) { return p1.name.compareTo(p2.name); } }); Joda-Beans: generated immutable @BeanDefinition public class Person implements ImmutableBean { @PropertyDefinition(validate = "notNull") private String name; @PropertyDefinition(validate = "notNull") private LocalDate birthDate; // ---- AUTOGENERATED START ---- // getters, equals, hashCode, toString, properties, builder // ----- AUTOGENERATED END ----- }
  • 61. Joda-Beans options ● Annotations allow field-level and bean-level control ● Control scope/style for getters/setters ● Supports pragmatic optional usage ● Can add any validation code ● Defaults/cross-validation for immutable bean builders ● Can default one property from another in builder ● Can fully override constructor
  • 62. Joda-Beans pros/cons ● No second class, proper immutable bean ○ resulting bean is same as manually written ● Adds abstraction for properties without reflection ○ key reason to use Joda-Beans, but requires runtime dependency ● Built in XML, JSON, Binary serialization ● Generated code is visible for debugging ○ more code to checkin, but easy to ignore in review ○ proper Javadoc ● Plugin for Maven, Gradle and Eclipse with M2E ○ anyone want to volunteer to write an IntelliJ one?
  • 64. Comparisons ● Annotation processor ○ AutoValue ○ Immutables ● Internal APIs ○ Lombok ● Same file regenerator ○ Joda-Beans
  • 65. Comparisons ● All can generate a lot of useful code ○ getters, factories, builders, equals, hashCode, toString ● Some can generate mutable beans ● Only Joda-Beans generates C# style properties ● Each project has a different trade-off
  • 66. Same class vs Generated class ● Same class (Joda-Beans, Lombok) ○ your code involves writing fields ○ caller sees concrete class ○ properly immutable ● Generated class (AutoValue, Immutables) ○ your code involves writing methods (more code) ○ caller sees abstract class or interface ○ is it really immutable? ○ IDE rename class typically breaks code
  • 67. Collections ● Immutable beans should use Guava ImmutableList ● Builder needs to take List and convert internally ● All except Lombok do this correctly
  • 68. Installation requirements ● AutoValue & Immutables use annotation processor ○ must be configured in IDE, extra plugin for Eclipse ● Lombok uses internal API hackery ○ requires specific Eclipse installation ● Joda-Beans runs as separate code regenerator ○ for Eclipse, just needs standard M2E
  • 69. AutoValue vs Immutables ● AutoValue ○ you write abstract class ○ generated class is package-scoped ○ cannot generate static factory ○ must write builder outline manually ● Immutables ○ you write interface or abstract class ○ generated class is public (can be made private or package-scoped) ○ static factory and builder in generated class ○ lots of flexibility
  • 70. Valid on checkout ● AutoValue, Immutables, Lombok ○ code invalid in IDE on checkout unless configured ○ only your code checked in ● Joda-Beans ○ code valid in IDE on checkout, even if not configured ○ your code and generated code checked in
  • 71. Evaluate yourself ● GitHub project with everything setup for comparison ○ https://github.com/jodastephen/compare-beangen ● Includes 4 tools discussed ○ plus VALJOGen, POJOmatic, Eclipse wizards and IntelliJ wizards ● Good project to play with each tool
  • 73. Summary ● All four tools have their sweet spot and trade off ○ AutoValue - simplicity, abstract class ○ Immutables - comprehensive, abstract class or interface ○ Lombok - almost a language extension, hacky implementation ○ Joda-Beans - C# style properties, runtime dependency
  • 74. Summary - personal view ● Use Joda-Beans if you like properties ○ Code should be valid on checkout ○ Immutable beans should be final ○ Want C# style properties ○ Hence I wrote and use Joda-Beans ● Otherwise, use Immutables @jodastephen http://blog.joda.org