SlideShare a Scribd company logo
1 of 39
1/39
Writing code
that writes code
by
LUONG Hoang Nguyen
Senior Java Technical Lead
ekino.
2/392/39
1. Context
2. Project Lombok
3. Alternatives
4. Conclusion
AGENDA
3/39
1.
Context
4/394/39
Developer job As programmers, we often find ourselves in a similar
position.
We need to achieve the
same functionality, but in different contexts.
We need to repeat information in different
places.
Sometimes we just need to protect ourselves from
carpal tunnel syndrome by
cutting down on repetitive typing
5/395/39
Boiler Plate Code
Syntax Verbosity
Problemsof
theIndustry
Non Standardization
Not following the standard code conventions
Human Error/Dependency
Repeatable things (defining Getters, Setters
etc.)
6/39
2.
Project Lombok
7/39
WHAT IS IT ?
8/398/39
•@Getter / @Setter
•@ToString
•@EqualsAndHashCode
•@Data
•@NoArgsConstructor
•@RequiredArgsConstructor
•@AllArgsConstructor
•@Cleanup
•@Synchronized
•@Slf4j
•@Builder
•val
Features
9/399/39
@Getter / Setter
Features
• Automatic Generation of getters and setters.
• Method will be public unless you explicitly specify an AccessLevel
• @Getter and/or @Setter annotation on class
• Disable getter/setter generation for any field by using the special
AccessLevel.NONE
• @NotNull for nullity check
10/3910/39
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
public class GetterSetterExample {
/**
* Age of the person. Water is wet.
*
* @param age New value for this person's age. Sky
is blue.
* @return The current value of this person's age.
Circles are round.
*/
@Getter @Setter private int age = 10;
/**
* Name of the person.
* -- SETTER --
* Changes the name of this person.
*
* @param name The new value.
*/
@Setter(AccessLevel.PROTECTED) private String name;
@Override public String toString() {
return String.format("%s (age: %d)", name, age);
}
}
public class GetterSetterExample {
/**
* Age of the person. Water is wet.
*
* @param age New value for this person's age. Sky is blue.
* @return The current value of this person's age. Circles are
round.
*/
private int age = 10;
/**
* Name of the person.
* -- SETTER --
* Changes the name of this person.
*
* @param name The new value.
*/
private String name;
@Override public String toString() {
return String.format("%s (age: %d)", name, age);
}
public int getAge() {
return this.age;
}
public void setAge(int age) {
this.age = age;
}
protected void setName(String name) {
this.name = name;
}
}
11/3911/39
@EqualsAndHash
Code
Features
• Generates hashCode and equals implementations from the fields (non-
static, non-transient)
• Parameters 
12/3912/39
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(exclude = { "id", "shape" })
class EqualsAndHashCodeExample {
private transient int transientVar = 10;
private String name;
private double score;
private Shape shape = new Square(5, 10);
private String[] tags;
private int id;
public String getName() {
return this.name;
}
}
public class EqualsAndHashCodeExample {
private transient int transientVar = 10;
private String name;
private double score;
private Shape shape = new Square(5, 10);
private String[] tags;
private int id;
public String getName() {
return this.name;
}
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof EqualsAndHashCodeExample)) {
return false;
}
final EqualsAndHashCodeExample other = (EqualsAndHashCodeExample) o;
if (!other.canEqual((Object) this)) {
return false;
}
final Object this$name = this.getName();
final Object other$name = other.getName();
if (this$name == null ? other$name != null : !this$name.equals(other$name)) {
return false;
}
if (Double.compare(this.score, other.score) != 0) {
return false;
}
if (!java.util.Arrays.deepEquals(this.tags, other.tags)) {
return false;
}
return true;
}
public int hashCode() {
final int PRIME = 59;
int result = 1;
final Object $name = this.getName();
result = result * PRIME + ($name == null ? 0 : $name.hashCode());
final long $score = Double.doubleToLongBits(this.score);
result = result * PRIME + (int) ($score >>> 32 ^ $score);
result = result * PRIME + java.util.Arrays.deepHashCode(this.tags);
return result;
}
protected boolean canEqual(Object other) {
return other instanceof EqualsAndHashCodeExample;
}
}
13/3913/39
@Data
Features
• All together now: A shortcut for @ToString, @EqualsAndHashCode,
@Getter on all fields, @Setter on all non-final fields, and
@RequiredArgsConstructor
• Included annotations with changed parameters can be defined along with
@Data
14/3914/39
import lombok.Data;
@Data
public class DataExample {
private final String name;
private double score;
}
public class DataExample {
private final String name;
private double score;
@java.beans.ConstructorProperties({ "name" })
public DataExample(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public double getScore() {
return this.score;
}
public void setScore(double score) {
this.score = score;
}
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof DataExample)) {
return false;
}
final DataExample other = (DataExample) o;
if (!other.canEqual((Object) this)) {
return false;
}
final Object this$name = this.name;
final Object other$name = other.name;
if (this$name == null ? other$name != null : !this$name.equals(other$name)) {
return false;
}
if (Double.compare(this.score, other.score) != 0) {
return false;
}
return true;
}
public int hashCode() {
final int PRIME = 59;
int result = 1;
final Object $name = this.name;
result = result * PRIME + ($name == null ? 0 : $name.hashCode());
final long $score = Double.doubleToLongBits(this.score);
result = result * PRIME + (int) ($score >>> 32 ^ $score);
return result;
}
protected boolean canEqual(Object other) {
return other instanceof DataExample;
}
public String toString() {
return "DataExample(name=" + this.name + ", score=" + this.score + ")";
}
}
15/3915/39
@NoArgsConstructor
@RequiredArgsConstructor
@AllArgsConstructor
Features
• Generates constructors that take no arguments, one argument per final /
non-null field, or one argument for every field.
• Specialized constructor can be made. Compile-time error in case of any
conflicts.
16/3916/39
@Cleanup
Features
• Automatic resource management: Call your close() methods safely with no
hassle.
@Cleanup
InputStream in=new FileInputStream("some/file");
• If the type of object you'd like to cleanup does not have a close() method,
but some other no-argument method like dispose() so write it as
@Cleanup("dispose")
TestClass t = new TestClass();
17/3917/39
@Builder
val
Features
• @Builder generates a static builder() method that returns a builder
instance. This builder instance can be used to build an object of the class
annotated with @Builder (here Person)
• Person.builder().name("Adam Savage").city("San
Francisco").job("Mythbusters").job("Unchained Reaction").build();
• val: You can use val as the type of a local variable declaration instead of
actually writing the type. This feature works on local variables and on
foreach loops only, not on fields
val example = new ArrayList<String>();
example.add("Hello, World!");
18/3918/39
import lombok.Builder;
@Builder
public class BuilderExample {
private String name;
private int age;
}
public class BuilderExample {
private String name;
private int age;
@java.beans.ConstructorProperties({ "name", "age" })
BuilderExample(String name, int age) {
this.name = name;
this.age = age;
}
public static BuilderExampleBuilder builder() {
return new BuilderExampleBuilder();
}
public static class BuilderExampleBuilder {
private String name;
private int age;
BuilderExampleBuilder() {
}
public BuilderExample.BuilderExampleBuilder name(String name) {
this.name = name;
return this;
}
public BuilderExample.BuilderExampleBuilder age(int age) {
this.age = age;
return this;
}
public BuilderExample build() {
return new BuilderExample(name, age);
}
public String toString() {
return "BuilderExampleBuilder(name=" + this.name + ", age=" + this.age + ")";
}
}
}
19/3919/39
• Generates Java Boilerplate
• Compile Time Only -> not affect performance for runtime
• For Eclipse and javac
• IntelliJ IDEA & NetBeans too
• Removable with delombok
• Know what is generated
Features
20/3920/39
How does it work? Java compilation has 3 stages:
In the Parse and Enter phase, the compiler parses source files into
an Abstract Syntax Tree (AST
In the Annotation Processing phase, custom annotation processors
are invoked
Annotation processors can do things like validate classes or
generate new resources, including source files.
In the last phase, Analyse and Generate, the compiler generates
class files (byte code) from the Abstract Syntax Trees generated in
phase 1
Project Lombok hooks itself into the compilation process as an
annotation processor. Normally, annotation processors only generate
new source files whereas Lombok modifies existing classes.
21/3921/39
Example • Example we create a very simple Lombok transformation that adds a
helloWorld method to any class annotated as @HelloWorld.
• The basic classes we need to write are:
- Annotation class
- Eclipse handler
- Javac handler (Intellj also supported this)
@HelloWorld
public class MyClass
{
}
public class MyClass {
public void helloWorld() {
System.out.println("Hello
World");
}
}
22/3922/39
Annotation
Example • At first, we just need to create an annotation called HelloWorld that can be
applied to classes.
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import
java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface HelloWorld {
}
23/3923/39
Handler
Example • Our handler will be adding a new Method Declaration to the Type
Declaration. A Method Declaration is composed of several components.
The AST for our Method Declaration will have this :
24/3924/39
Handler Logic
Example • Our handle method will need to do the following:
1. Mark annotation as processed
2. Create the helloWorld method
3. Inject the helloWorld method into the AST of the annotated class
25/3925/39
Lombok provides our handler with the AST of the annotation node. We know
that the annotation can only be applied to a Type. To get the AST for the Type
(Class), we call annotationNode.up(). The annotation is a child of the Type
AST, so by calling up() we get the parent AST which is the Type AST we need
to modify.
Javac Handler
Example
@ProviderFor(JavacAnnotationHandler.class)
public class HandleHelloWorld implements JavacAnnotationHandler<HelloWorld>{
public boolean handle(AnnotationValues<HelloWorld> annotation, JCAnnotation ast,
JavacNode annotationNode) {
JavacHandlerUtil.markAnnotationAsProcessed(annotationNode, HelloWorld.class);
JavacNode typeNode = annotationNode.up();
if(notAClass(typeNode)) {
annotationNode.addError("@HelloWorld is only supported on a class.");
return false;
}
JCMethodDecl helloWorldMethod = createHelloWorld(typeNode);
JavacHandlerUtil.injectMethod(typeNode, helloWorldMethod);
return true;
}
…
}
26/3926/39
• Start with a method node.
• Add the return type, parameters, access level, throw clause, etc to the
method node.
• Create an expression statement to represent System.out.println("Hello
World")
• Add the expression to the method node.
Javac Handler
Hello world method
Example
private JCMethodDecl createHelloWorld(JavacNode type) {
TreeMaker treeMaker = type.getTreeMaker();
JCModifiers modifiers = treeMaker.Modifiers(Modifier.PUBLIC);
List<JCTypeParameter> methodGenericTypes = List.<JCTypeParameter>nil();
JCExpression methodType = treeMaker.TypeIdent(TypeTag.VOID);
Name methodName = type.toName("helloWorld");
List<JCVariableDecl> methodParameters = List.<JCVariableDecl>nil();
List<JCExpression> methodThrows = List.<JCExpression>nil();
JCExpression printlnMethod =
JavacHandlerUtil.chainDots(treeMaker, type, "System", "out", "println");
List<JCExpression> printlnArgs = List.<JCExpression>of(treeMaker.Literal("hello world"));
JCMethodInvocation printlnInvocation =
treeMaker.Apply(List.<JCExpression>nil(), printlnMethod, printlnArgs);
JCBlock methodBody =
treeMaker.Block(0, List.<JCStatement>of(treeMaker.Exec(printlnInvocation)));
JCExpression defaultValue = null;
return treeMaker.MethodDef(
modifiers,
methodName,
methodType,
methodGenericTypes,
methodParameters,
methodThrows,
methodBody,
defaultValue
);
}
27/3927/39
@UUIDColumn
@JsonColumn
Custom Annotations • We can create custom annotations that helpful for our projects. It will
make standardization for our coding.
@Entity
@Data
public class TestModelEntity {
@Id
@UUIDColumn
private UUID id;
@JsonColumn
private Model model;
….
}
@Entity
public class TestModelEntity {
@Id
@Type(
type = "pg-uuid"
)
@GeneratedValue(
generator = "uuid2"
)
private UUID id;
@Type(
type = "JSONB",
parameters = { @Parameter(
name = "class",
value = "com.ekino.lombok.sample.Model"
)}
)
private Model model;
….
}
28/39
3.
Alternatives
29/3929/39
Google Auto AutoFactory
JSR-330-compatible factories
AutoService
Provider-configuration files for ServiceLoader
AutoValue
Immutable value-type code generation for Java 1.6+ .
Common
Helper utilities for writing annotation processors.
30/3930/39
AutoValue
• You write an abstract class
• It has abstract accessors, but no fields
• Annotate it with @AutoValue
• Javac generates a concrete subclass for you
• Callers only ever see the parent type
Google Auto
31/3931/39
AutoValue
• What you write (plain Java).
import com.google.auto.value.AutoValue;
@AutoValue
public abstract class Foo {
public static Foo create(String text, int number) {
// defensive copies, preconditions
return new AutoValue_Foo(text, number);
}
/** Documentation here. */
public abstract String text(); // or getText(), if you like
/** Documentation here. */
public abstract int number();
}
Google Auto
32/3932/39
AutoValue
• What code does that generate?
final class AutoValue_Foo extends Foo { // (note: NOT public!)
private final String text;
private final int number;
AutoValue_Foo(String text, int number) {
if (text == null) {
throw new NullPointerException("text");
}
this.text = text;
this.number = number;
}
@Override public String text() {
return text;
}
@Override public int number() {
return number;
}
// and the customary equals/hashCode/toString.
}
Google Auto
33/39
3.
Conclusion
34/3934/39
Advantages
• User writes only plain old Java code
• No runtime impact
• no dependency (@AutoValue has source retention)
• No magical modifying of existing classes
• Still just a single javac pass to compile!
Google Auto
35/3935/39
Disadvantages
• Bootstrap can be annoying—when you first type new AutoValue_Foo it may go
red in the IDE
• Some once-per-project build setup required
• Not support setter for AutoValue
• AutoValue does introduce some fragility.
• The generator has to choose the order of constructor parameters somehow,
so it uses the order in which the accessors appear in the source file.
• This means an innocent refactoring to reorder those accessors could break
your tests
Google Auto
36/3936/39
Advantages
• User writes only plain old Java code
• No runtime impact
• no dependency (annotations has source retention)
• Support delombok
• Maximally concise value classes.
• There is plugin support to integrate with IDE like Lombok plugin for Intellij
Project Lombok
37/3937/39
Disadvantages
• The compiler hacks are non-standard and fragile.
• Somebody may mention that the code is no longer really Java – the code
lose its WYSIWYG feel.
Project Lombok
38/3938/39
• Project Lombok https://projectlombok.org/
• Google Auto https://github.com/google/auto
•http://notatube.blogspot.com/2010/12/project-lombok-creating-custom.html
•http://www.ibm.com/developerworks/library/j-lombok/
•https://docs.google.com/presentation/d/14u_h-
lMn7f1rXE1nDiLX0azS3IkgjGl5uxp5jGJ75RE/edit#slide=id.g2a5e9c4a8_01
39
•The pragmatic programmer - book by Andy Hunt and Dave Thomas
Resources
39/3939/39
Thank you
• LUONG Hoang Nguyen
• Email: hoang-nguyen.luong@ekino.com
• Phone: 0914 974197

More Related Content

What's hot

Porting Applications From Oracle To PostgreSQL
Porting Applications From Oracle To PostgreSQLPorting Applications From Oracle To PostgreSQL
Porting Applications From Oracle To PostgreSQLPeter Eisentraut
 
Introduction to Asynchronous scala
Introduction to Asynchronous scalaIntroduction to Asynchronous scala
Introduction to Asynchronous scalaStratio
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modelingCodemotion
 
Real Life Clean Architecture
Real Life Clean ArchitectureReal Life Clean Architecture
Real Life Clean ArchitectureMattia Battiston
 
Introduction to reactive programming & ReactiveCocoa
Introduction to reactive programming & ReactiveCocoaIntroduction to reactive programming & ReactiveCocoa
Introduction to reactive programming & ReactiveCocoaFlorent Pillet
 
Angular Weekend
Angular WeekendAngular Weekend
Angular WeekendTroy Miles
 
Cracking JWT tokens: a tale of magic, Node.JS and parallel computing
Cracking JWT tokens: a tale of magic, Node.JS and parallel computingCracking JWT tokens: a tale of magic, Node.JS and parallel computing
Cracking JWT tokens: a tale of magic, Node.JS and parallel computingLuciano Mammino
 
Eclipse Day India 2015 - Java 8 Overview
Eclipse Day India 2015 - Java 8 OverviewEclipse Day India 2015 - Java 8 Overview
Eclipse Day India 2015 - Java 8 OverviewEclipse Day India
 
Node Boot Camp
Node Boot CampNode Boot Camp
Node Boot CampTroy Miles
 
Java collections the force awakens
Java collections  the force awakensJava collections  the force awakens
Java collections the force awakensRichardWarburton
 
Engineering Efficiency in LINE
Engineering Efficiency in LINEEngineering Efficiency in LINE
Engineering Efficiency in LINEHuy Do
 
Language Integrated Query - LINQ
Language Integrated Query - LINQLanguage Integrated Query - LINQ
Language Integrated Query - LINQDoncho Minkov
 
JavaScript - An Introduction
JavaScript - An IntroductionJavaScript - An Introduction
JavaScript - An IntroductionManvendra Singh
 
Node.js System: The Approach
Node.js System: The ApproachNode.js System: The Approach
Node.js System: The ApproachHaci Murat Yaman
 

What's hot (20)

Porting Applications From Oracle To PostgreSQL
Porting Applications From Oracle To PostgreSQLPorting Applications From Oracle To PostgreSQL
Porting Applications From Oracle To PostgreSQL
 
Introduction to Asynchronous scala
Introduction to Asynchronous scalaIntroduction to Asynchronous scala
Introduction to Asynchronous scala
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
 
LINQ
LINQLINQ
LINQ
 
Real Life Clean Architecture
Real Life Clean ArchitectureReal Life Clean Architecture
Real Life Clean Architecture
 
Introduction to reactive programming & ReactiveCocoa
Introduction to reactive programming & ReactiveCocoaIntroduction to reactive programming & ReactiveCocoa
Introduction to reactive programming & ReactiveCocoa
 
Smart Migration to JDK 8
Smart Migration to JDK 8Smart Migration to JDK 8
Smart Migration to JDK 8
 
Angular Weekend
Angular WeekendAngular Weekend
Angular Weekend
 
Cracking JWT tokens: a tale of magic, Node.JS and parallel computing
Cracking JWT tokens: a tale of magic, Node.JS and parallel computingCracking JWT tokens: a tale of magic, Node.JS and parallel computing
Cracking JWT tokens: a tale of magic, Node.JS and parallel computing
 
Eclipse Day India 2015 - Java 8 Overview
Eclipse Day India 2015 - Java 8 OverviewEclipse Day India 2015 - Java 8 Overview
Eclipse Day India 2015 - Java 8 Overview
 
Node Boot Camp
Node Boot CampNode Boot Camp
Node Boot Camp
 
Java collections the force awakens
Java collections  the force awakensJava collections  the force awakens
Java collections the force awakens
 
Linq
LinqLinq
Linq
 
Engineering Efficiency in LINE
Engineering Efficiency in LINEEngineering Efficiency in LINE
Engineering Efficiency in LINE
 
Javantura v3 - Going Reactive with RxJava – Hrvoje Crnjak
Javantura v3 - Going Reactive with RxJava – Hrvoje CrnjakJavantura v3 - Going Reactive with RxJava – Hrvoje Crnjak
Javantura v3 - Going Reactive with RxJava – Hrvoje Crnjak
 
Language Integrated Query - LINQ
Language Integrated Query - LINQLanguage Integrated Query - LINQ
Language Integrated Query - LINQ
 
JavaScript - An Introduction
JavaScript - An IntroductionJavaScript - An Introduction
JavaScript - An Introduction
 
Node.js System: The Approach
Node.js System: The ApproachNode.js System: The Approach
Node.js System: The Approach
 
Java 8: the good parts!
Java 8: the good parts!Java 8: the good parts!
Java 8: the good parts!
 
Spring batch
Spring batchSpring batch
Spring batch
 

Similar to TechkTalk #12 Grokking: Writing code that writes code – Nguyen Luong

Lombok Features
Lombok FeaturesLombok Features
Lombok Features文峰 眭
 
Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...
Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...
Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...Tudor Dragan
 
CSharp presentation and software developement
CSharp presentation and software developementCSharp presentation and software developement
CSharp presentation and software developementfrwebhelp
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to javaciklum_ods
 
Enhancing Productivity and Insight A Tour of JDK Tools Progress Beyond Java 17
Enhancing Productivity and Insight  A Tour of JDK Tools Progress Beyond Java 17Enhancing Productivity and Insight  A Tour of JDK Tools Progress Beyond Java 17
Enhancing Productivity and Insight A Tour of JDK Tools Progress Beyond Java 17Ana-Maria Mihalceanu
 
Smoothing Your Java with DSLs
Smoothing Your Java with DSLsSmoothing Your Java with DSLs
Smoothing Your Java with DSLsintelliyole
 
React Native One Day
React Native One DayReact Native One Day
React Native One DayTroy Miles
 
Code Documentation. That ugly thing...
Code Documentation. That ugly thing...Code Documentation. That ugly thing...
Code Documentation. That ugly thing...Christos Manios
 
Building High Perf Web Apps - IE8 Firestarter
Building High Perf Web Apps - IE8 FirestarterBuilding High Perf Web Apps - IE8 Firestarter
Building High Perf Web Apps - IE8 FirestarterMithun T. Dhar
 
API workshop: Deep dive into Java
API workshop: Deep dive into JavaAPI workshop: Deep dive into Java
API workshop: Deep dive into JavaTom Johnson
 
ITB_2023_CommandBox_Task_Runners_Brad_Wood.pdf
ITB_2023_CommandBox_Task_Runners_Brad_Wood.pdfITB_2023_CommandBox_Task_Runners_Brad_Wood.pdf
ITB_2023_CommandBox_Task_Runners_Brad_Wood.pdfOrtus Solutions, Corp
 
New features in jdk8 iti
New features in jdk8 itiNew features in jdk8 iti
New features in jdk8 itiAhmed mar3y
 
Back-2-Basics: .NET Coding Standards For The Real World (2011)
Back-2-Basics: .NET Coding Standards For The Real World (2011)Back-2-Basics: .NET Coding Standards For The Real World (2011)
Back-2-Basics: .NET Coding Standards For The Real World (2011)David McCarter
 

Similar to TechkTalk #12 Grokking: Writing code that writes code – Nguyen Luong (20)

Lombok Features
Lombok FeaturesLombok Features
Lombok Features
 
java Statements
java Statementsjava Statements
java Statements
 
Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...
Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...
Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...
 
CSharp presentation and software developement
CSharp presentation and software developementCSharp presentation and software developement
CSharp presentation and software developement
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to java
 
Java For Automation
Java   For AutomationJava   For Automation
Java For Automation
 
Enhancing Productivity and Insight A Tour of JDK Tools Progress Beyond Java 17
Enhancing Productivity and Insight  A Tour of JDK Tools Progress Beyond Java 17Enhancing Productivity and Insight  A Tour of JDK Tools Progress Beyond Java 17
Enhancing Productivity and Insight A Tour of JDK Tools Progress Beyond Java 17
 
Oops lecture 1
Oops lecture 1Oops lecture 1
Oops lecture 1
 
Smoothing Your Java with DSLs
Smoothing Your Java with DSLsSmoothing Your Java with DSLs
Smoothing Your Java with DSLs
 
AkJS Meetup - ES6++
AkJS Meetup -  ES6++AkJS Meetup -  ES6++
AkJS Meetup - ES6++
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
React Native One Day
React Native One DayReact Native One Day
React Native One Day
 
Code Documentation. That ugly thing...
Code Documentation. That ugly thing...Code Documentation. That ugly thing...
Code Documentation. That ugly thing...
 
Building High Perf Web Apps - IE8 Firestarter
Building High Perf Web Apps - IE8 FirestarterBuilding High Perf Web Apps - IE8 Firestarter
Building High Perf Web Apps - IE8 Firestarter
 
API workshop: Deep dive into Java
API workshop: Deep dive into JavaAPI workshop: Deep dive into Java
API workshop: Deep dive into Java
 
ITB_2023_CommandBox_Task_Runners_Brad_Wood.pdf
ITB_2023_CommandBox_Task_Runners_Brad_Wood.pdfITB_2023_CommandBox_Task_Runners_Brad_Wood.pdf
ITB_2023_CommandBox_Task_Runners_Brad_Wood.pdf
 
New features in jdk8 iti
New features in jdk8 itiNew features in jdk8 iti
New features in jdk8 iti
 
Back-2-Basics: .NET Coding Standards For The Real World (2011)
Back-2-Basics: .NET Coding Standards For The Real World (2011)Back-2-Basics: .NET Coding Standards For The Real World (2011)
Back-2-Basics: .NET Coding Standards For The Real World (2011)
 
JAVA_BASICS.ppt
JAVA_BASICS.pptJAVA_BASICS.ppt
JAVA_BASICS.ppt
 
Csharp_mahesh
Csharp_maheshCsharp_mahesh
Csharp_mahesh
 

More from Grokking VN

Grokking Techtalk #46: Lessons from years hacking and defending Vietnamese banks
Grokking Techtalk #46: Lessons from years hacking and defending Vietnamese banksGrokking Techtalk #46: Lessons from years hacking and defending Vietnamese banks
Grokking Techtalk #46: Lessons from years hacking and defending Vietnamese banksGrokking VN
 
Grokking Techtalk #45: First Principles Thinking
Grokking Techtalk #45: First Principles ThinkingGrokking Techtalk #45: First Principles Thinking
Grokking Techtalk #45: First Principles ThinkingGrokking VN
 
Grokking Techtalk #42: Engineering challenges on building data platform for M...
Grokking Techtalk #42: Engineering challenges on building data platform for M...Grokking Techtalk #42: Engineering challenges on building data platform for M...
Grokking Techtalk #42: Engineering challenges on building data platform for M...Grokking VN
 
Grokking Techtalk #43: Payment gateway demystified
Grokking Techtalk #43: Payment gateway demystifiedGrokking Techtalk #43: Payment gateway demystified
Grokking Techtalk #43: Payment gateway demystifiedGrokking VN
 
Grokking Techtalk #40: Consistency and Availability tradeoff in database cluster
Grokking Techtalk #40: Consistency and Availability tradeoff in database clusterGrokking Techtalk #40: Consistency and Availability tradeoff in database cluster
Grokking Techtalk #40: Consistency and Availability tradeoff in database clusterGrokking VN
 
Grokking Techtalk #40: AWS’s philosophy on designing MLOps platform
Grokking Techtalk #40: AWS’s philosophy on designing MLOps platformGrokking Techtalk #40: AWS’s philosophy on designing MLOps platform
Grokking Techtalk #40: AWS’s philosophy on designing MLOps platformGrokking VN
 
Grokking Techtalk #39: Gossip protocol and applications
Grokking Techtalk #39: Gossip protocol and applicationsGrokking Techtalk #39: Gossip protocol and applications
Grokking Techtalk #39: Gossip protocol and applicationsGrokking VN
 
Grokking Techtalk #39: How to build an event driven architecture with Kafka ...
 Grokking Techtalk #39: How to build an event driven architecture with Kafka ... Grokking Techtalk #39: How to build an event driven architecture with Kafka ...
Grokking Techtalk #39: How to build an event driven architecture with Kafka ...Grokking VN
 
Grokking Techtalk #37: Data intensive problem
 Grokking Techtalk #37: Data intensive problem Grokking Techtalk #37: Data intensive problem
Grokking Techtalk #37: Data intensive problemGrokking VN
 
Grokking Techtalk #37: Software design and refactoring
 Grokking Techtalk #37: Software design and refactoring Grokking Techtalk #37: Software design and refactoring
Grokking Techtalk #37: Software design and refactoringGrokking VN
 
Grokking TechTalk #35: Efficient spellchecking
Grokking TechTalk #35: Efficient spellcheckingGrokking TechTalk #35: Efficient spellchecking
Grokking TechTalk #35: Efficient spellcheckingGrokking VN
 
Grokking Techtalk #34: K8S On-premise: Incident & Lesson Learned ZaloPay Mer...
 Grokking Techtalk #34: K8S On-premise: Incident & Lesson Learned ZaloPay Mer... Grokking Techtalk #34: K8S On-premise: Incident & Lesson Learned ZaloPay Mer...
Grokking Techtalk #34: K8S On-premise: Incident & Lesson Learned ZaloPay Mer...Grokking VN
 
Grokking TechTalk #33: High Concurrency Architecture at TIKI
Grokking TechTalk #33: High Concurrency Architecture at TIKIGrokking TechTalk #33: High Concurrency Architecture at TIKI
Grokking TechTalk #33: High Concurrency Architecture at TIKIGrokking VN
 
Grokking TechTalk #33: Architecture of AI-First Systems - Engineering for Big...
Grokking TechTalk #33: Architecture of AI-First Systems - Engineering for Big...Grokking TechTalk #33: Architecture of AI-First Systems - Engineering for Big...
Grokking TechTalk #33: Architecture of AI-First Systems - Engineering for Big...Grokking VN
 
SOLID & Design Patterns
SOLID & Design PatternsSOLID & Design Patterns
SOLID & Design PatternsGrokking VN
 
Grokking TechTalk #31: Asynchronous Communications
Grokking TechTalk #31: Asynchronous CommunicationsGrokking TechTalk #31: Asynchronous Communications
Grokking TechTalk #31: Asynchronous CommunicationsGrokking VN
 
Grokking TechTalk #30: From App to Ecosystem: Lessons Learned at Scale
Grokking TechTalk #30: From App to Ecosystem: Lessons Learned at ScaleGrokking TechTalk #30: From App to Ecosystem: Lessons Learned at Scale
Grokking TechTalk #30: From App to Ecosystem: Lessons Learned at ScaleGrokking VN
 
Grokking TechTalk #29: Building Realtime Metrics Platform at LinkedIn
Grokking TechTalk #29: Building Realtime Metrics Platform at LinkedInGrokking TechTalk #29: Building Realtime Metrics Platform at LinkedIn
Grokking TechTalk #29: Building Realtime Metrics Platform at LinkedInGrokking VN
 
Grokking TechTalk #27: Optimal Binary Search Tree
Grokking TechTalk #27: Optimal Binary Search TreeGrokking TechTalk #27: Optimal Binary Search Tree
Grokking TechTalk #27: Optimal Binary Search TreeGrokking VN
 
Grokking TechTalk #26: Kotlin, Understand the Magic
Grokking TechTalk #26: Kotlin, Understand the MagicGrokking TechTalk #26: Kotlin, Understand the Magic
Grokking TechTalk #26: Kotlin, Understand the MagicGrokking VN
 

More from Grokking VN (20)

Grokking Techtalk #46: Lessons from years hacking and defending Vietnamese banks
Grokking Techtalk #46: Lessons from years hacking and defending Vietnamese banksGrokking Techtalk #46: Lessons from years hacking and defending Vietnamese banks
Grokking Techtalk #46: Lessons from years hacking and defending Vietnamese banks
 
Grokking Techtalk #45: First Principles Thinking
Grokking Techtalk #45: First Principles ThinkingGrokking Techtalk #45: First Principles Thinking
Grokking Techtalk #45: First Principles Thinking
 
Grokking Techtalk #42: Engineering challenges on building data platform for M...
Grokking Techtalk #42: Engineering challenges on building data platform for M...Grokking Techtalk #42: Engineering challenges on building data platform for M...
Grokking Techtalk #42: Engineering challenges on building data platform for M...
 
Grokking Techtalk #43: Payment gateway demystified
Grokking Techtalk #43: Payment gateway demystifiedGrokking Techtalk #43: Payment gateway demystified
Grokking Techtalk #43: Payment gateway demystified
 
Grokking Techtalk #40: Consistency and Availability tradeoff in database cluster
Grokking Techtalk #40: Consistency and Availability tradeoff in database clusterGrokking Techtalk #40: Consistency and Availability tradeoff in database cluster
Grokking Techtalk #40: Consistency and Availability tradeoff in database cluster
 
Grokking Techtalk #40: AWS’s philosophy on designing MLOps platform
Grokking Techtalk #40: AWS’s philosophy on designing MLOps platformGrokking Techtalk #40: AWS’s philosophy on designing MLOps platform
Grokking Techtalk #40: AWS’s philosophy on designing MLOps platform
 
Grokking Techtalk #39: Gossip protocol and applications
Grokking Techtalk #39: Gossip protocol and applicationsGrokking Techtalk #39: Gossip protocol and applications
Grokking Techtalk #39: Gossip protocol and applications
 
Grokking Techtalk #39: How to build an event driven architecture with Kafka ...
 Grokking Techtalk #39: How to build an event driven architecture with Kafka ... Grokking Techtalk #39: How to build an event driven architecture with Kafka ...
Grokking Techtalk #39: How to build an event driven architecture with Kafka ...
 
Grokking Techtalk #37: Data intensive problem
 Grokking Techtalk #37: Data intensive problem Grokking Techtalk #37: Data intensive problem
Grokking Techtalk #37: Data intensive problem
 
Grokking Techtalk #37: Software design and refactoring
 Grokking Techtalk #37: Software design and refactoring Grokking Techtalk #37: Software design and refactoring
Grokking Techtalk #37: Software design and refactoring
 
Grokking TechTalk #35: Efficient spellchecking
Grokking TechTalk #35: Efficient spellcheckingGrokking TechTalk #35: Efficient spellchecking
Grokking TechTalk #35: Efficient spellchecking
 
Grokking Techtalk #34: K8S On-premise: Incident & Lesson Learned ZaloPay Mer...
 Grokking Techtalk #34: K8S On-premise: Incident & Lesson Learned ZaloPay Mer... Grokking Techtalk #34: K8S On-premise: Incident & Lesson Learned ZaloPay Mer...
Grokking Techtalk #34: K8S On-premise: Incident & Lesson Learned ZaloPay Mer...
 
Grokking TechTalk #33: High Concurrency Architecture at TIKI
Grokking TechTalk #33: High Concurrency Architecture at TIKIGrokking TechTalk #33: High Concurrency Architecture at TIKI
Grokking TechTalk #33: High Concurrency Architecture at TIKI
 
Grokking TechTalk #33: Architecture of AI-First Systems - Engineering for Big...
Grokking TechTalk #33: Architecture of AI-First Systems - Engineering for Big...Grokking TechTalk #33: Architecture of AI-First Systems - Engineering for Big...
Grokking TechTalk #33: Architecture of AI-First Systems - Engineering for Big...
 
SOLID & Design Patterns
SOLID & Design PatternsSOLID & Design Patterns
SOLID & Design Patterns
 
Grokking TechTalk #31: Asynchronous Communications
Grokking TechTalk #31: Asynchronous CommunicationsGrokking TechTalk #31: Asynchronous Communications
Grokking TechTalk #31: Asynchronous Communications
 
Grokking TechTalk #30: From App to Ecosystem: Lessons Learned at Scale
Grokking TechTalk #30: From App to Ecosystem: Lessons Learned at ScaleGrokking TechTalk #30: From App to Ecosystem: Lessons Learned at Scale
Grokking TechTalk #30: From App to Ecosystem: Lessons Learned at Scale
 
Grokking TechTalk #29: Building Realtime Metrics Platform at LinkedIn
Grokking TechTalk #29: Building Realtime Metrics Platform at LinkedInGrokking TechTalk #29: Building Realtime Metrics Platform at LinkedIn
Grokking TechTalk #29: Building Realtime Metrics Platform at LinkedIn
 
Grokking TechTalk #27: Optimal Binary Search Tree
Grokking TechTalk #27: Optimal Binary Search TreeGrokking TechTalk #27: Optimal Binary Search Tree
Grokking TechTalk #27: Optimal Binary Search Tree
 
Grokking TechTalk #26: Kotlin, Understand the Magic
Grokking TechTalk #26: Kotlin, Understand the MagicGrokking TechTalk #26: Kotlin, Understand the Magic
Grokking TechTalk #26: Kotlin, Understand the Magic
 

Recently uploaded

EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 

Recently uploaded (20)

EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 

TechkTalk #12 Grokking: Writing code that writes code – Nguyen Luong

  • 1. 1/39 Writing code that writes code by LUONG Hoang Nguyen Senior Java Technical Lead ekino.
  • 2. 2/392/39 1. Context 2. Project Lombok 3. Alternatives 4. Conclusion AGENDA
  • 4. 4/394/39 Developer job As programmers, we often find ourselves in a similar position. We need to achieve the same functionality, but in different contexts. We need to repeat information in different places. Sometimes we just need to protect ourselves from carpal tunnel syndrome by cutting down on repetitive typing
  • 5. 5/395/39 Boiler Plate Code Syntax Verbosity Problemsof theIndustry Non Standardization Not following the standard code conventions Human Error/Dependency Repeatable things (defining Getters, Setters etc.)
  • 9. 9/399/39 @Getter / Setter Features • Automatic Generation of getters and setters. • Method will be public unless you explicitly specify an AccessLevel • @Getter and/or @Setter annotation on class • Disable getter/setter generation for any field by using the special AccessLevel.NONE • @NotNull for nullity check
  • 10. 10/3910/39 import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; public class GetterSetterExample { /** * Age of the person. Water is wet. * * @param age New value for this person's age. Sky is blue. * @return The current value of this person's age. Circles are round. */ @Getter @Setter private int age = 10; /** * Name of the person. * -- SETTER -- * Changes the name of this person. * * @param name The new value. */ @Setter(AccessLevel.PROTECTED) private String name; @Override public String toString() { return String.format("%s (age: %d)", name, age); } } public class GetterSetterExample { /** * Age of the person. Water is wet. * * @param age New value for this person's age. Sky is blue. * @return The current value of this person's age. Circles are round. */ private int age = 10; /** * Name of the person. * -- SETTER -- * Changes the name of this person. * * @param name The new value. */ private String name; @Override public String toString() { return String.format("%s (age: %d)", name, age); } public int getAge() { return this.age; } public void setAge(int age) { this.age = age; } protected void setName(String name) { this.name = name; } }
  • 11. 11/3911/39 @EqualsAndHash Code Features • Generates hashCode and equals implementations from the fields (non- static, non-transient) • Parameters 
  • 12. 12/3912/39 import lombok.EqualsAndHashCode; @EqualsAndHashCode(exclude = { "id", "shape" }) class EqualsAndHashCodeExample { private transient int transientVar = 10; private String name; private double score; private Shape shape = new Square(5, 10); private String[] tags; private int id; public String getName() { return this.name; } } public class EqualsAndHashCodeExample { private transient int transientVar = 10; private String name; private double score; private Shape shape = new Square(5, 10); private String[] tags; private int id; public String getName() { return this.name; } public boolean equals(Object o) { if (o == this) { return true; } if (!(o instanceof EqualsAndHashCodeExample)) { return false; } final EqualsAndHashCodeExample other = (EqualsAndHashCodeExample) o; if (!other.canEqual((Object) this)) { return false; } final Object this$name = this.getName(); final Object other$name = other.getName(); if (this$name == null ? other$name != null : !this$name.equals(other$name)) { return false; } if (Double.compare(this.score, other.score) != 0) { return false; } if (!java.util.Arrays.deepEquals(this.tags, other.tags)) { return false; } return true; } public int hashCode() { final int PRIME = 59; int result = 1; final Object $name = this.getName(); result = result * PRIME + ($name == null ? 0 : $name.hashCode()); final long $score = Double.doubleToLongBits(this.score); result = result * PRIME + (int) ($score >>> 32 ^ $score); result = result * PRIME + java.util.Arrays.deepHashCode(this.tags); return result; } protected boolean canEqual(Object other) { return other instanceof EqualsAndHashCodeExample; } }
  • 13. 13/3913/39 @Data Features • All together now: A shortcut for @ToString, @EqualsAndHashCode, @Getter on all fields, @Setter on all non-final fields, and @RequiredArgsConstructor • Included annotations with changed parameters can be defined along with @Data
  • 14. 14/3914/39 import lombok.Data; @Data public class DataExample { private final String name; private double score; } public class DataExample { private final String name; private double score; @java.beans.ConstructorProperties({ "name" }) public DataExample(String name) { this.name = name; } public String getName() { return this.name; } public double getScore() { return this.score; } public void setScore(double score) { this.score = score; } public boolean equals(Object o) { if (o == this) { return true; } if (!(o instanceof DataExample)) { return false; } final DataExample other = (DataExample) o; if (!other.canEqual((Object) this)) { return false; } final Object this$name = this.name; final Object other$name = other.name; if (this$name == null ? other$name != null : !this$name.equals(other$name)) { return false; } if (Double.compare(this.score, other.score) != 0) { return false; } return true; } public int hashCode() { final int PRIME = 59; int result = 1; final Object $name = this.name; result = result * PRIME + ($name == null ? 0 : $name.hashCode()); final long $score = Double.doubleToLongBits(this.score); result = result * PRIME + (int) ($score >>> 32 ^ $score); return result; } protected boolean canEqual(Object other) { return other instanceof DataExample; } public String toString() { return "DataExample(name=" + this.name + ", score=" + this.score + ")"; } }
  • 15. 15/3915/39 @NoArgsConstructor @RequiredArgsConstructor @AllArgsConstructor Features • Generates constructors that take no arguments, one argument per final / non-null field, or one argument for every field. • Specialized constructor can be made. Compile-time error in case of any conflicts.
  • 16. 16/3916/39 @Cleanup Features • Automatic resource management: Call your close() methods safely with no hassle. @Cleanup InputStream in=new FileInputStream("some/file"); • If the type of object you'd like to cleanup does not have a close() method, but some other no-argument method like dispose() so write it as @Cleanup("dispose") TestClass t = new TestClass();
  • 17. 17/3917/39 @Builder val Features • @Builder generates a static builder() method that returns a builder instance. This builder instance can be used to build an object of the class annotated with @Builder (here Person) • Person.builder().name("Adam Savage").city("San Francisco").job("Mythbusters").job("Unchained Reaction").build(); • val: You can use val as the type of a local variable declaration instead of actually writing the type. This feature works on local variables and on foreach loops only, not on fields val example = new ArrayList<String>(); example.add("Hello, World!");
  • 18. 18/3918/39 import lombok.Builder; @Builder public class BuilderExample { private String name; private int age; } public class BuilderExample { private String name; private int age; @java.beans.ConstructorProperties({ "name", "age" }) BuilderExample(String name, int age) { this.name = name; this.age = age; } public static BuilderExampleBuilder builder() { return new BuilderExampleBuilder(); } public static class BuilderExampleBuilder { private String name; private int age; BuilderExampleBuilder() { } public BuilderExample.BuilderExampleBuilder name(String name) { this.name = name; return this; } public BuilderExample.BuilderExampleBuilder age(int age) { this.age = age; return this; } public BuilderExample build() { return new BuilderExample(name, age); } public String toString() { return "BuilderExampleBuilder(name=" + this.name + ", age=" + this.age + ")"; } } }
  • 19. 19/3919/39 • Generates Java Boilerplate • Compile Time Only -> not affect performance for runtime • For Eclipse and javac • IntelliJ IDEA & NetBeans too • Removable with delombok • Know what is generated Features
  • 20. 20/3920/39 How does it work? Java compilation has 3 stages: In the Parse and Enter phase, the compiler parses source files into an Abstract Syntax Tree (AST In the Annotation Processing phase, custom annotation processors are invoked Annotation processors can do things like validate classes or generate new resources, including source files. In the last phase, Analyse and Generate, the compiler generates class files (byte code) from the Abstract Syntax Trees generated in phase 1 Project Lombok hooks itself into the compilation process as an annotation processor. Normally, annotation processors only generate new source files whereas Lombok modifies existing classes.
  • 21. 21/3921/39 Example • Example we create a very simple Lombok transformation that adds a helloWorld method to any class annotated as @HelloWorld. • The basic classes we need to write are: - Annotation class - Eclipse handler - Javac handler (Intellj also supported this) @HelloWorld public class MyClass { } public class MyClass { public void helloWorld() { System.out.println("Hello World"); } }
  • 22. 22/3922/39 Annotation Example • At first, we just need to create an annotation called HelloWorld that can be applied to classes. import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.TYPE) @Retention(RetentionPolicy.SOURCE) public @interface HelloWorld { }
  • 23. 23/3923/39 Handler Example • Our handler will be adding a new Method Declaration to the Type Declaration. A Method Declaration is composed of several components. The AST for our Method Declaration will have this :
  • 24. 24/3924/39 Handler Logic Example • Our handle method will need to do the following: 1. Mark annotation as processed 2. Create the helloWorld method 3. Inject the helloWorld method into the AST of the annotated class
  • 25. 25/3925/39 Lombok provides our handler with the AST of the annotation node. We know that the annotation can only be applied to a Type. To get the AST for the Type (Class), we call annotationNode.up(). The annotation is a child of the Type AST, so by calling up() we get the parent AST which is the Type AST we need to modify. Javac Handler Example @ProviderFor(JavacAnnotationHandler.class) public class HandleHelloWorld implements JavacAnnotationHandler<HelloWorld>{ public boolean handle(AnnotationValues<HelloWorld> annotation, JCAnnotation ast, JavacNode annotationNode) { JavacHandlerUtil.markAnnotationAsProcessed(annotationNode, HelloWorld.class); JavacNode typeNode = annotationNode.up(); if(notAClass(typeNode)) { annotationNode.addError("@HelloWorld is only supported on a class."); return false; } JCMethodDecl helloWorldMethod = createHelloWorld(typeNode); JavacHandlerUtil.injectMethod(typeNode, helloWorldMethod); return true; } … }
  • 26. 26/3926/39 • Start with a method node. • Add the return type, parameters, access level, throw clause, etc to the method node. • Create an expression statement to represent System.out.println("Hello World") • Add the expression to the method node. Javac Handler Hello world method Example private JCMethodDecl createHelloWorld(JavacNode type) { TreeMaker treeMaker = type.getTreeMaker(); JCModifiers modifiers = treeMaker.Modifiers(Modifier.PUBLIC); List<JCTypeParameter> methodGenericTypes = List.<JCTypeParameter>nil(); JCExpression methodType = treeMaker.TypeIdent(TypeTag.VOID); Name methodName = type.toName("helloWorld"); List<JCVariableDecl> methodParameters = List.<JCVariableDecl>nil(); List<JCExpression> methodThrows = List.<JCExpression>nil(); JCExpression printlnMethod = JavacHandlerUtil.chainDots(treeMaker, type, "System", "out", "println"); List<JCExpression> printlnArgs = List.<JCExpression>of(treeMaker.Literal("hello world")); JCMethodInvocation printlnInvocation = treeMaker.Apply(List.<JCExpression>nil(), printlnMethod, printlnArgs); JCBlock methodBody = treeMaker.Block(0, List.<JCStatement>of(treeMaker.Exec(printlnInvocation))); JCExpression defaultValue = null; return treeMaker.MethodDef( modifiers, methodName, methodType, methodGenericTypes, methodParameters, methodThrows, methodBody, defaultValue ); }
  • 27. 27/3927/39 @UUIDColumn @JsonColumn Custom Annotations • We can create custom annotations that helpful for our projects. It will make standardization for our coding. @Entity @Data public class TestModelEntity { @Id @UUIDColumn private UUID id; @JsonColumn private Model model; …. } @Entity public class TestModelEntity { @Id @Type( type = "pg-uuid" ) @GeneratedValue( generator = "uuid2" ) private UUID id; @Type( type = "JSONB", parameters = { @Parameter( name = "class", value = "com.ekino.lombok.sample.Model" )} ) private Model model; …. }
  • 29. 29/3929/39 Google Auto AutoFactory JSR-330-compatible factories AutoService Provider-configuration files for ServiceLoader AutoValue Immutable value-type code generation for Java 1.6+ . Common Helper utilities for writing annotation processors.
  • 30. 30/3930/39 AutoValue • You write an abstract class • It has abstract accessors, but no fields • Annotate it with @AutoValue • Javac generates a concrete subclass for you • Callers only ever see the parent type Google Auto
  • 31. 31/3931/39 AutoValue • What you write (plain Java). import com.google.auto.value.AutoValue; @AutoValue public abstract class Foo { public static Foo create(String text, int number) { // defensive copies, preconditions return new AutoValue_Foo(text, number); } /** Documentation here. */ public abstract String text(); // or getText(), if you like /** Documentation here. */ public abstract int number(); } Google Auto
  • 32. 32/3932/39 AutoValue • What code does that generate? final class AutoValue_Foo extends Foo { // (note: NOT public!) private final String text; private final int number; AutoValue_Foo(String text, int number) { if (text == null) { throw new NullPointerException("text"); } this.text = text; this.number = number; } @Override public String text() { return text; } @Override public int number() { return number; } // and the customary equals/hashCode/toString. } Google Auto
  • 34. 34/3934/39 Advantages • User writes only plain old Java code • No runtime impact • no dependency (@AutoValue has source retention) • No magical modifying of existing classes • Still just a single javac pass to compile! Google Auto
  • 35. 35/3935/39 Disadvantages • Bootstrap can be annoying—when you first type new AutoValue_Foo it may go red in the IDE • Some once-per-project build setup required • Not support setter for AutoValue • AutoValue does introduce some fragility. • The generator has to choose the order of constructor parameters somehow, so it uses the order in which the accessors appear in the source file. • This means an innocent refactoring to reorder those accessors could break your tests Google Auto
  • 36. 36/3936/39 Advantages • User writes only plain old Java code • No runtime impact • no dependency (annotations has source retention) • Support delombok • Maximally concise value classes. • There is plugin support to integrate with IDE like Lombok plugin for Intellij Project Lombok
  • 37. 37/3937/39 Disadvantages • The compiler hacks are non-standard and fragile. • Somebody may mention that the code is no longer really Java – the code lose its WYSIWYG feel. Project Lombok
  • 38. 38/3938/39 • Project Lombok https://projectlombok.org/ • Google Auto https://github.com/google/auto •http://notatube.blogspot.com/2010/12/project-lombok-creating-custom.html •http://www.ibm.com/developerworks/library/j-lombok/ •https://docs.google.com/presentation/d/14u_h- lMn7f1rXE1nDiLX0azS3IkgjGl5uxp5jGJ75RE/edit#slide=id.g2a5e9c4a8_01 39 •The pragmatic programmer - book by Andy Hunt and Dave Thomas Resources
  • 39. 39/3939/39 Thank you • LUONG Hoang Nguyen • Email: hoang-nguyen.luong@ekino.com • Phone: 0914 974197