18
Ted’s Tool Time Ted Vinke First8 Code Generation with Groovy, Lombok, AutoValue and Immutables July 2016

Code Generation with Groovy, Lombok, AutoValue and Immutables - Teds Tool Time

Embed Size (px)

Citation preview

Ted’s Tool TimeTed VinkeFirst8

Code Generation with Groovy,

Lombok, AutoValue and Immutables

July 2016

Reducing boilerplate

Project Lombok

https://projectlombok.org/

@NonNull

@Cleanup

@Getter / @Setter

@ToString

@EqualsAndHashCode

@NoArgsConstructor,

@RequiredArgsConstructor and

@AllArgsConstructor

@Data

Project Lombok

import lombok.AllArgsConstructor; import lombok.EqualsAndHashCode; import lombok.ToString;

@ToString @AllArgsConstructor @EqualsAndHashCode public class Person {

private String lastName;private String firstName;

}

Value objects

Immutability in plain old Java

● final

● final private

● construction in a single step

● defensive copying

● no mutators

● ...

public final class Planet {

private final double mass; private final String name;private final Date dateOfDiscovery;

public Planet (double mass, String mame, Date dateOfDiscovery) {this.mass = mass;this.name = name;this.dateOfDiscovery = new Date(dateOfDiscovery.getTime());

}

public double getMass() {return mass;

}

public String getName() {return name;

}

public Date getDateOfDiscovery() {return new Date(dateOfDiscovery.getTime());

}

}

Equals, hashCode in plain-old Java

public final class Location {private final String countryCode;private final int priority;

public Location(String countryCode, int priority) {this.countryCode = countryCode;this.priority = priority;

}

@Overridepublic int hashCode() {

final int prime = 31;int result = 1;result = prime * result + ((countryCode == null) ? 0 :

countryCode.hashCode());result = prime * result + priority;return result;

}

@Overridepublic boolean equals(Object obj) {

if (this == obj)return true;

if (obj == null)return false;

if (!(obj instanceof Location))return false;

Location other = (Location) obj;if (countryCode == null) {

if (other.countryCode != null)return false;

} else if (!countryCode.equals(other.countryCode))return false;

if (priority != other.priority)return false;

return true;}

}

@Value

Project Lombok

import lombok.experimental.Value;

@Value public class Location {

String countryCode;int priority;

}

Groovy

http://www.groovy-lang.org/

And...

Dates, Cloneables and arrays are

defensively copied on the way

in (constructor) and out

(getters).

Collections and Maps are wrapped

by immutable wrapper classes.

@Immutable

import groovy.transform.Immutable

@Immutableclass Location {

String countryCodeint priority

}

AutoValue

https://github.com/google/auto/tree/

master/value

Generated immutable value classes for

Java 1.6+

@AutoValue

Google AutoValue

import com.google.auto.value.AutoValue;

@AutoValue abstract class Location {

static Location create(String countryCode, int priority) {return new AutoValue_Location(countryCode, priority)

}

abstract String countryCode()abstract int priority()

}

Generated

AutoValue_Location.java

import javax.annotation.Generated;

@Generated("com.google.auto.value.processor.AutoValueProcessor") final class AutoValue_Location extends Location {

private final String countryCode; private final int priority;

AutoValue_Location( String countryCode, int priority) {

if (countryCode == null) { throw new NullPointerException("Null countryCode");

} ...

}

@Override String countryCode() {

return countryCode; }

Immutables

http://immutables.github.io/

@Value.Immutable

import org.immutables.value.Value;

@Value.Immutable abstract class Location {

abstract String countryCode()abstract int priority()

}

Generated

ImmutableLocation.java

import javax.annotation.Generated;

@SuppressWarnings("all") @Generated({"Immutables.generator", "Location"}) final class ImmutableLocation extends Location {

private final String countryCode; private final int priority;

private ImmutableLocation(String countryCode, int priority) {

this.countryCode = countryCode; this.priority = priority;

}

@Override String countryCode() {

return countryCode; }

public static ImmutablePerson.Builder builder() { return new ImmutablePerson.Builder();

}

Annotation processing

Lombok, AutoValue, and Immutables all employ annotation processing via

javac, Groovy uses groovyc

AutoValue and Immutables generate new source - which extend template class

e.g. Location.java -> AutoValue_Location.java extends Location

Groovy and Lombok modify the AST and enhances compiled class

That's it!

Project Lombok - https://projectlombok.org/

Groovy - http://www.groovy-lang.org/

AutoValue - https://github.com/google/auto/blob/master/value

Immutables - http://immutables.github.io/

http://culttt.com/2014/04/30/difference-entities-value-objects/

http://marxsoftware.blogspot.nl/2016/06/lombok-autovalue-immutables.htmlThank you