Presentation Project Lombok: Bye Bye Boilerplate
In this presentation, the developers of lombok, Reinier Zwitserloot and Roel Spilker, will show the audience what lombok is about, and how you can use it to eliminate boilerplate from your java code. For example, instead of writing out common boilerplate such as getters, setters, toString, equals, and hashCode implementations, you can use lombok's @Data annotation. Lombok hooks into your compiler and IDE so that their interpretation of your source includes these methods, while you never actually see any of them in your editor. For IDEs, this means that you get all the benefits, such as auto-completion, the methods show up in your outline views, and search tools such as 'go to declaration'continue to work. While most IDEs offer a feature to generate the boilerplate, this is little help when reading the resulting code, and such code is much harder to maintain.
Published on: 2009-11-26T15:19:14.000Z
Channel: Devoxx'09 (all)
Tags: framework annotations devoxx 2009 conference javase lombok
Speakers:
Roel Spilker
Roel Spilker is a technology evangelist at TOPdesk. He's been a professional java programmer and teacher since 1999. Roel has been a fan of compile-time checking. His first open source project to leverage the compiler was the SPI project which simplifies the usage of the Service Provider API. Together with Reinier Zwitserloot he is the inventor of Project Lombok, a compiler/IDE plugin to bring the java programming language into the next decennium.
Reinier Zwitserloot
Reinier Zwitserloot is the founder and lead developer of Tipit.to, a web service that enables tipjars on the web. He's been interested in programming language evolution ever since he started working with Java professionally 10 years ago. As a result, together with Roel Spilker he is the inventor of Project Lombok, a compiler/IDE plugin to bring the java programming language into the next decennium.
Slides:
Project Lombok:
Project Lombok:
Bye Bye Boilerplate
http://projectlombok.org/d09
http://projectlombok.org/d09
http://projectlombok.org/d09
www.devoxx.com
Reinier Zwitserloot - Founder & developer
Reinier Zwitserloot - Founder & developer
www.devoxx.com
Reinier Zwitserloot - Founder & developer
Reinier Zwitserloot - Founder & developer
www.devoxx.com
Roel Spilker - Senior Developer & java trainer
4207m
4207m
4392m
4392m
DEMO
DEMO
www.devoxx.com
WHAT IS LOMBOK?
WHAT IS LOMBOK?
Picture
Picture
Picture
Picture
Picture
Picture
Safety Harness Rope Carabiners
Safety Harness Rope Carabiners
@Getter and @Setter
@Getter and @Setter
Never write public int getFoo() {return foo;} again.
@Getter and @Setter
@Getter and @Setter
Never write public int getFoo() {return foo;} again.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; public class Mountain { @Getter @Setter private int altitude = 4392; @Setter(AccessLevel.PROTECTED) private String name; @Setter @NonNull private String country; @Override public String toString() { return String.format("%s (%d m)", getName(), getAltitude()); }
}
@Getter and @Setter
@Getter and @Setter
Never write public int getFoo() {return foo;} again.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; public class Mountain { @Getter @Setter private int altitude = 4392; @Setter(AccessLevel.PROTECTED) private String name; @Setter @NonNull private String country; @Override public String toString() { return String.format("%s (%d m)", getName(), getAltitude()); }
}
public int getAltitude() { return altitude; }
@Getter and @Setter
@Getter and @Setter
Never write public int getFoo() {return foo;} again.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; public class Mountain { @Getter @Setter private int altitude = 4392; @Setter(AccessLevel.PROTECTED) private String name; @Setter @NonNull private String country; @Override public String toString() { return String.format("%s (%d m)", getName(), getAltitude()); }
}
@Getter and @Setter
@Getter and @Setter
Never write public int getFoo() {return foo;} again.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; public class Mountain { @Getter @Setter private int altitude = 4392; @Setter(AccessLevel.PROTECTED) private String name; @Setter @NonNull private String country; @Override public String toString() { return String.format("%s (%d m)", getName(), getAltitude()); }
}
public void setAltitude(int altitude) { this.altitude = altitude; }
@Getter and @Setter
@Getter and @Setter
Never write public int getFoo() {return foo;} again.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; public class Mountain { @Getter @Setter private int altitude = 4392; @Setter(AccessLevel.PROTECTED) private String name; @Setter @NonNull private String country; @Override public String toString() { return String.format("%s (%d m)", getName(), getAltitude()); }
}
@Getter and @Setter
@Getter and @Setter
Never write public int getFoo() {return foo;} again.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; public class Mountain { @Getter @Setter private int altitude = 4392; @Setter(AccessLevel.PROTECTED) private String name; @Setter @NonNull private String country; @Override public String toString() { return String.format("%s (%d m)", getName(), getAltitude()); }
}
@Getter and @Setter
@Getter and @Setter
Never write public int getFoo() {return foo;} again.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; public class Mountain { @Getter @Setter private int altitude = 4392; @Setter(AccessLevel.PROTECTED) private String name; @Setter @NonNull private String country; @Override public String toString() { return String.format("%s (%d m)", getName(), getAltitude()); }
}
public void setCountry(@NonNull String country) { if (country == null) throw new NullPointerException("country"); this.country = country; }
@ToString
@ToString
No need to start a debugger to see your fields: Just let lombok generate a toString for you!
@ToString
@ToString
No need to start a debugger to see your fields: Just let lombok generate a toString for you!
01 import lombok.ToString; 02 03 @ToString 04 public class Gear { 05 private static final Logger LOGGER = getLogger(); 06 private String name; 07 private Material material = Material.HEMP; 08 private String[] category; 09 private int id; 10
@ToString
@ToString
No need to start a debugger to see your fields: Just let lombok generate a toString for you!
01 import lombok.ToString; 02 03 @ToString 04 public class Gear { 05 private static final Logger LOGGER = getLogger(); 06 private String name; 07 private Material material = Material.HEMP; 08 private String[] category; 09 private int id; 10 Gear(name="Rope", material=HEMP, category=[foo, bar])
@ToString
@ToString
No need to start a debugger to see your fields: Just let lombok generate a toString for you!
01 02 03 04 05 06 07 08 09 10
import lombok.ToString; @ToString(excludes="id") public class Gear { private static final Logger LOGGER = getLogger(); private String name; private Material material = Material.HEMP; private String[] category; private int id;
}
Gear(name="Rope", material=HEMP, category=[foo, bar])
@EqualsAndHashCode
@EqualsAndHashCode
Equality made easy: Generates hashCode and equals implementations from the fields of your object.
@EqualsAndHashCode
@EqualsAndHashCode
Equality made easy: Generates hashCode and equals implementations from the fields of your object.
01 02 03 04 05 06 07 08 09 10
import lombok.EqualsAndHashCode; @EqualsAndHashCode(exclude={"id", "equipment"}) public class Mountaineer { private String name; private double highestPoint; private List equipment; private int age; private long id; }
@EqualsAndHashCode
@EqualsAndHashCode
Equality made easy: Generates hashCode and equals implementations from the fields of your object.
01 02 03 04 05 06 07 08 09 10
import lombok.EqualsAndHashCode; @EqualsAndHashCode(of={"id"}) public class Mountaineer { private String name; private double highestPoint; private List equipment; private int age; private long id; }
@Data
@Data
All together now: A shortcut for @ToString, @EqualsAndHashCode, @Getter on all fields, and @Setter on all non-final fields. You even get a free constructor to initialize your final fields!
@Data
@Data
All together now: A shortcut for @ToString, @EqualsAndHashCode, @Getter on all fields, and @Setter on all non-final fields. You even get a free constructor to initialize your final fields!
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19
import import import import
lombok.AccessLevel; lombok.Setter; lombok.Data; lombok.ToString;
@Data public class Mountain { private final String name; private final int altitude; @Setter(AccessLevel.PACKAGE) private Country country; private final double latitude, longitude; @ToString(includeFieldNames=false) @Data(staticConstructor="of") public static class Goal { private final String name; private final T target; }
}
@Data
@Data
All together now: A shortcut for @ToString, @EqualsAndHashCode, @Getter on all fields, and @Setter on all non-final fields. You even get a free constructor to initialize your final fields!
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19
import import import import
lombok.AccessLevel; lombok.Setter; lombok.Data; lombok.ToString;
@Data public class Mountain { private final String name; private final int altitude; @Setter(AccessLevel.PACKAGE) private Country country; private final double latitude, longitude; @ToString(includeFieldNames=false) @Data(staticConstructor="of") public static class Goal { private final String name; private final T target; }
}
@Data
@Data
All together now: A shortcut for @ToString, @EqualsAndHashCode, @Getter on all fields, and @Setter on all non-final fields. You even get a free constructor to initialize your final fields!
01 import lombok.AccessLevel; 02 import lombok.Setter; 03 import lombok.Data; 04 import lombok.ToString; 05 06 @Data public class Mountain { 07 private final String name; 08 private final int altitude; 09 @Setter(AccessLevel.PACKAGE) Goal private Goal.of("Devoxx Audience Size", 1000); goal = Country country; 10 11 private final double latitude, longitude; 12 13 @ToString(includeFieldNames=false) 14 @Data(staticConstructor="of") 15 public static class Goal { 16 private final String name; 17 private final T target; 18 } 19 }
@Cleanup
@Cleanup
Automatic resource management: Call your close() methods safely with no hassle.
@Cleanup
@Cleanup
Automatic resource management: Call your close() methods safely with no hassle.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16
import lombok.Cleanup; import java.io.*; public class MountainStore { public void save(File file) throws IOException { @Cleanup InputStream in = getClass().getResourceAsStream( "mountains.dat"); @Cleanup OutputStream out = new FileOutputStream(file); byte[] b = new byte[10000]; while (true) { int r = in.read(b); if (r == -1) break; out.write(b, 0, r); } } }
01 import java.io.*; 02 03 public class MountainStore { 04 public void save(File file) throws IOException { 05 InputStream in = getClass().getResourceAsStream( 05 "mountains.dat"); 06 try { 07 OutputStream out = new FileOutputStream(file); 08 try { 09 by
01 import java.io.*; 02 03 public class MountainStore { 04 public void save(File file) throws IOException { 05 InputStream in = getClass().getResourceAsStream( 05 "mountains.dat"); 06 try { 07 OutputStream out = new FileOutputStream(file); 08 try { 09 byte[] b = new byte[10000]; 10 while (true) { 11 int r = in.read(b); 12 if (r == -1) break; 13 out.write(b, 0, r); 14 } 15 } finally { 16 out.close(); 17 } 18 } finally { 19 in.close(); 20 } 21 } 22 }
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16
import lombok.Cleanup; import java.io.*; public class MountainStore { public void save(File file) throws IOException { @Cleanup InputStream in = getClass().getResourceAsStream( "mountains.dat"); @Cleanup OutputStream out = new FileOutputStream(file); byte[] b = new byte[10000]; while (true) { int r = in.read(b); if (r == -1) break; out.write(b, 0, r); } } }
@Synchronized
@Synchronized
synchronized done right: Don't expose your locks.
@Synchronized
@Synchronized
synchronized done right: Don't expose your locks.
01 public class Flag { 02 private static TreeSet flags; 03 04 public synchronized static int getHighest() { 05 return flags.last().getAltitude(); 06 } 07 08 public synchronized void plant(Mountain mountain) { 09 mountain.plant(this); 10 System.out.println("top of the world!"); 11 } 12 }
@Synchronized
@Synchronized
synchronized done right: Don't expose your locks.
01 public class Flag { 02 private static final Object $LOCK = new Object[0]; 03 private final Object $lock = new Object[0]; 04 02 private static TreeSet flags; 03 04 public static int getHighest() { 06 synchronized($LOCK) { 05 return flags.last().g
01 public class Flag { 02 private static final Object $LOCK = new Object[0]; 03 private final Object $lock = new Object[0]; 04 02 private static TreeSet flags; 03 04 public static int getHighest() { 06 synchronized($LOCK) { 05 return flags.last().getAltitude(); 06 } 06 } 07 08 public void plant(Mountain mountain) { 06 synchronized($lock) { 09 mountain.plant(this); 10 System.out.println("top of the world!"); 11 } 11 } 12 }
01 import lombok.Synchronized; 02 03 public class Flag { 04 private static TreeSet flags; 05 06 @Synchronized 07 public static int getHighest() { 08 return flags.last().getAltitude(); 09 } 10 11 @Synchronized 12 public void plant(Mountain mountain)
01 import lombok.Synchronized; 02 03 public class Flag { 04 private static TreeSet flags; 05 06 @Synchronized 07 public static int getHighest() { 08 return flags.last().getAltitude(); 09 } 10 11 @Synchronized 12 public void plant(Mountain mountain) { 13 mountain.plant(this); 14 System.out.println("top of the world!"); 15 } 16 }
@SneakyThrows
@SneakyThrows
To boldly throw checked exceptions where no one has thrown them before!
@SneakyThrows
@SneakyThrows
To boldly throw checked exceptions where no one has thrown them before!
01 import lombok.SneakyThrows; 02 03 public class SneakyThrowsExample implements Runnable { 04 05 public static String utf8ToString(byte[] bytes) { 06 return new String(bytes, "UTF-8"); 07 } 08 09 10 public void run() { 11 throw new Throwable(); 12 } 13 }
@SneakyThrows
@SneakyThrows
To boldly throw checked exceptions where no one has thrown them before!
01 import lombok.SneakyThrows; 02 03 public class SneakyThrowsExample implements Runnable { 04 @SneakyThrows(UnsupportedEncodingException.class) 05 public static String utf8ToString(byte[] bytes) { 06 return new String(bytes, "UTF-8"); 07 } 08 09 @SneakyThrows 10 public void run() { 11 throw new Throwable(); 12 } 13 }
Picture
Picture
Picture
Picture
Picture
Picture
Picture
Picture
Picture
Picture
class MountainStore implements Iterable { @Delegate Iterable mountains; public MountainStore() { this(Collections.emptyList()); } public MountainStore(List mountains) { this.mountains = mountains; } public static void main(S
class MountainStore implements Iterable { @Delegate Iterable mountains; public MountainStore() { this(Collections.emptyList()); } public MountainStore(List mountains) { this.mountains = mountains; } public static void main(String[] args) { MountainStore store = new MountainStore(); for (Mountain mountain : store) { System.out.println(mountain); } }
}
@Mixin(RelativeOperations.class) @Data class Mountain implements Comparable { private final String name; private final int altitude; public int compareTo(Mountain m) { return altitude.compareTo(m.altitude); } public static void main(String[] ar
@Mixin(RelativeOperations.class) @Data class Mountain implements Comparable { private final String name; private final int altitude; public int compareTo(Mountain m) { return altitude.compareTo(m.altitude); } public static void main(String[] args) { Mountain raoul = new Mountain("Raoul", 4207); Mountain rainier = new Mountain("Rainier", 4392); System.out.println(rainier.isGreaterThan(raoul)); }
}
class Literals { private static final Pattern WIN_PATH = /[A-Z]:\(.*\)*/i; private static final String MESSAGE = """ Can’t find configuration file. You need to check: - If your computer is connected to the network - If the file Z:\mountains\mountains.dat
class Literals { private static final Pattern WIN_PATH = /[A-Z]:\(.*\)*/i; private static final String MESSAGE = """ Can’t find configuration file. You need to check: - If your computer is connected to the network - If the file Z:\mountains\mountains.dat exists""";
}
import java.util.Collections.sort extends java.util.List; class MountainStore { public static void main(String[] args) { List mountainNames = new ArrayList(Arrays.asList("Raoul", "Rainier")); System.out.println(mountainNames.sort()); } }
import java.util.Collections.sort extends java.util.List; class MountainStore { public static void main(String[] args) { List mountainNames = new ArrayList(Arrays.asList("Raoul", "Rainier")); System.out.println(mountainNames.sort()); } }
untitled
public class Climber { private final List mountainsClimbed; public List climbedAbove(int altitude) { return [Mountain m : mountainsClimbed where(m.getAltitude() > altitude) select(m.getName())]; }
public class Climber { private final List mountainsClimbed; public List climbedAbove(int altitude) { return [Mountain m : mountainsClimbed where(m.getAltitude() > altitude) select(m.getName())]; }
}
Picture
DEMO
DEMO
www.devoxx.com
http://projectlombok.org
http://projectlombok.org