Java APIs
you should know
by
• Lead of JUG Dortmund
• JSR EG member
• Java Developer @ Canoo Engineering AG
• JavaOne Rockstar, Java Champion
• I ❤ Star Wars
www.guigarage.com@hendrikEbbers
Hendrik Ebbers
by
www.guigarage.com@hendrikEbbers
Hendrik Ebbers
by
www.guigarage.com@hendrikEbbers
null Plugin @
null
you should knowJava byAPIs
How to handle null
blog.takipi.com
you should knowJava byAPIs
How to handle null
NullPointerException
you should knowJava byAPIs
How to handle null
• All of us have seen more than enough
NullPointerExceptions
• Java contains some APIs to tame the
beast
you should knowJava byAPIs
How to handle null
• Before we try to avoid NPEs we should
have a look how to handle null the
right way
• Java has null for a reason. Just use it.
you should knowJava byAPIs
How to handle null
public long getPeriode(final Date start, final Date end) {
return end.getTime() - start.getTime();
}
• This method is a typically bad
example for NPEs / null values and
how to deal with them
• Do you have an idea why? ?
you should knowJava byAPIs
How to handle null
public long getPeriode(final Date start, final Date end) {
return end.getTime() - start.getTime();
}
Exception in thread "main" java.lang.NullPointerException
at com.guigarage.sample.Example.getPeriode(Example.java:11)
which date is null?
you should knowJava byAPIs
How to handle null
public Locale(String language, String country, String variant) {

if (language== null || country == null || variant == null) {

throw new NullPointerException();

}

. . .

}
JDK code . . .
you should knowJava byAPIs
How to handle null/**
* . . .
* @throws NullPointerException if start or end is null
*/
public long getPeriode(final Date start, final Date end) {
if(start == null) {
throw new NullPointerException("start must not be null");
}
if(end == null) {
throw new NullPointerException("end must not be null");
}
return end.getTime() - start.getTime();
}
you should knowJava byAPIs
How to handle null
/**
* . . .
* @throws NullPointerException if start or end is null
*/
public long getPeriode(final Date start, final Date end) {
Objects.requireNonNull(start, "start must not be null");
Objects.requireNonNull(end, "end must not be null");
return end.getTime() - start.getTime();
}
you should knowJava byAPIs
How to handle null
• You should use it in constructors, too
public class Periode {
private final Date start;
private final Date end;
public Periode(final Date start, final Date end) {
start = Objects.requireNonNull(start, "start must not be null");
end = Objects.requireNonNull(end, "end must not be null");
}
}
you should knowJava byAPIs
How to handle null
• Make your own util methods
public class MyUtils {
public static <T> T requireNonNull(final T value, final String name) {
return Objects.requireNonNull(value, name + " must not be null");
}
}
you should knowJava byAPIs
How to handle null
• Sometime you don't want to throw a
NPE
• In that case the use of default values is
an option
you should knowJava byAPIs
How to handle null
public boolean containsA(final String input) {
String currentInput = input;
if(currentInput == null) {
currentInput = "";
}
return currentInput.contains("A");
}
you should knowJava byAPIs
How to handle null
• Sometime you don't want to throw a NPE
• In that case the use of default values is
an option
• Java 8 provides the Optional class to
simplify this
you should knowJava byAPIs
How to handle null
public boolean containsA(final String input) {
return Optional.ofNullable(input).orElse("").contains("A");
}
create a new
Optional that wraps
a value
returns the internal value
or the given value if the
internal value is null
you should knowJava byAPIs
How to handle null
• You can use Optional internally in your
method logic
• You can use Optional as a return value
of a method
• You should not use Optional as a param
you should knowJava byAPIs
How to handle null
public Optional<Entity> findByName(final String name) {
Objects.requireNonNull(name, "name must not be null");
String query = "Select entity where name = " + name;
return Optional.ofNullable(database.executeQuery(query));
}
• This methods can be used as a starting
point for a fluent API
findByName("Java").ifPresent(entity -> table.add(entity));
you should knowJava byAPIs
How to handle null
• Another example that provides the id of
an selected element
maybe nothing is
selected
list shows "Movie"
objects that provide
title and id
you should knowJava byAPIs
How to handle null
final Integer selectedId = Optional.ofNullable(list.getSelected())
.map(i -> i.getId())
.orElse(null);
• Another example that provides the id of
an selected element
you should knowJava byAPIs
How to handle null
• Since autoboxing is a cool feature in
general it sucks if you run in NPEs
• Using Optional can help you to avoid
this exceptions
you should knowJava byAPIs
• Let's have a look at a bean -> entity
converter







What could possibly go wrong
How to handle null
public class MyBean {
public Integer getCount();
}
public class MyEntity {
public void setCount(int c);
}
?
you should knowJava byAPIs
public class MyBean {
public Integer getCount();
}
How to handle null
hint : this could return null
public class MyEntity {
public void setCount(int c);
}
you should knowJava byAPIs
public MyEntity convert(final MyBean bean) {
Objects.requireNonNull(bean, "bean must not be null");
MyEntity entity = new MyEntity();
entity.setCount(bean.getCount());
return entity;
}
How to handle null
might throw a NPE since we can't
pass null as value for a primitive
you should knowJava byAPIs
public MyEntity convert(final MyBean bean) {
Objects.requireNonNull(bean, "bean must not be null");
MyEntity entity = new MyEntity();
entity.setCount(Optional.ofNullable(bean.getCount()).orElse(0));
return entity;
}
How to handle null
default value
Service Provider
Interface
you should knowJava byAPIs
Service Provider Interface
• Based on Interfaces it's quite easy to
define a general service and several
implementations in Java
you should knowJava byAPIs
Service Provider Interface
public interface MathOperation {
String getSign();
double calc(double valA, double valB);
}
you should knowJava byAPIs
Service Provider Interface
• We can provide several
implementations of math operations
• AddOperation
• SubstractOperation
you should knowJava byAPIs
Service Provider Interface
public class Multiply implements MathOperation {
public String getSign() { return "*";}
double calc(double valA, double valB){
return valA * valB;
}
}
you should knowJava byAPIs
Service Provider Interface
• Instances of the implementations can
be accessed by using the general
interface
• All instances can simply be stored in a
collection
you should knowJava byAPIs
Service Provider Interface
List<MathOperation> operations = new ArrayList<>();
operations.add(new MultipyOperation());
operations.add(new AddOperation());
operations.add(new DivideOperation());
operations.add(new SubstractOperation());
operations.forEach(o -> {
System.out.println("Supported Operation: " + o.getSign());
});
you should knowJava byAPIs
Service Provider Interface
• With Java 8 default methods we can
even define default logic for some
parts of the service
• Use defaults only if it really makes
sense!
you should knowJava byAPIs
Service Provider Interface
public interface MathOperation {
String getSign();
double calc(double valA, double valB);
default String getHelp() {
return "No help text for sign" + getSign();
}
}
you should knowJava byAPIs
Service Provider Interface
• Let's think about a bigger application
• Often based on several modules /
jars
• Several jars contains several service
implementations
you should knowJava byAPIs
Service Provider Interface
Application
Basic Math
Module
Math Def
Module
Special Math
Module
contains the interface
you should knowJava byAPIs
Service Provider Interface
Application
Basic Math
Module
Math Def
Module
Special Math
Module
contains the interface
contains implementations
contains implementations
you should knowJava byAPIs
Service Provider Interface
Application
Basic Math
Module
Math Def
Module
Special Math
Module
contains the interface
contains implementations
contains implementations
use implementations
you should knowJava byAPIs
Service Provider Interface
Application
Basic Math
Module
Math Def
Module
Special Math
Module
depends on
depends on
depends ondepends on
you should knowJava byAPIs
Service Provider Interface
Application
Basic Math
Module
Math Def
Module
Special Math
Module
One Million Dollar
Question
you should knowJava byAPIs
Service Provider Interface
• Where should we define the following
method?
public List<MathOperation> getAllImplInClasspath();
?
you should knowJava byAPIs
Service Provider Interface
• We can't define it in the "Math Def
Module" since this module has no
dependency to any implementation
• Method would return

an empty list
you should knowJava byAPIs
Service Provider Interface
• We can't define it in the "Basic Math" or
the "Special Math" since this modules
don't know all implementations.
• Method would not

return all 

implementations
you should knowJava byAPIs
Service Provider Interface
• Only the "Application" module knows all
implementations since it's the only
module that depends on all other
modules
you should knowJava byAPIs
Service Provider Interface
Basic Math
Module
Math Def
Module
Special Math
Module
Algebra Math
Module
Geometry
Math Module
• Let's add some complexity
you should knowJava byAPIs
Service Provider Interface
Customer A
Application
Basic Math
Module
Math Def
Module
Special Math
Module
Algebra Math
Module
Geometry
Math Module
Customer B
Application
Customer C
Application
you should knowJava byAPIs
Service Provider Interface
• We don't want to implement the



for each application
• We need something new that loads all
implementations dynamically
public List<MathOperation> getAllImplInClasspath();
you should knowJava byAPIs
Service Provider Interface
• Service Provider Interface (SPI)
provides a simple API to solve this issue
• Could be used to create a minimal but
powerful Plug In API
you should knowJava byAPIs
Service Provider Interface
• Start by creating an interface
public interface MathOperation {
String getSign();
double calc(double valA, double valB);
}
we already have it
you should knowJava byAPIs
Service Provider Interface
• Each module that provides
implementations of the interface most
provide a service file
• File must be located under META-INF/
services/
you should knowJava byAPIs
Service Provider Interface
• Name of the file must be equals to the
interface name
META-INF/services/com.canoo.math.MathOperation
file name
you should knowJava byAPIs
Service Provider Interface
• File simply contains names of all
implementations
com.canoo.basic.AddOperation

com.canoo.basic.MinusOperation
define one
implementation per line
you should knowJava byAPIs
Service Provider Interface
• The Service Provider Interface (SPI) will
automatically find all implementations
at runtime
• Instances of the classes will
automatically be created
• Default constructor is needed
you should knowJava byAPIs
Service Provider Interface
• You can simply iterate over all
implementations
Iterator<MathOperation> iterator = ServiceLoader.load(MathOperation.class).iterator();


while (iterator.hasNext()) {

MathOperation operation = iterator.next();

}
you should knowJava byAPIs
Service Provider Interface
• At the end we can implement the



method simple in the "Math Def Module"
• The service provider 

will automatically find

all implementations
public List<MathOperation> getAllImplInClasspath();
@nnotations
you should knowJava byAPIs
Annotations
• Let's start with a quiz :)
• How many Java annotations are used
in the code?
?
you should knowJava byAPIs
Annotations/**

* A helper class

* @see Class#getModifiers()

*

* @author Hendrik Ebbers
* @deprecated

*/
@Deprectaded
public class Helper {
@Important
private Logger logger = new Logger();
/**

* Return {@code true} if the integer argument includes the {@code private} modifier, {@code false} otherwise.

*

* @param mod a set of modifiers

* @return {@code true} if {@code mod} includes the {@code private} modifier; {@code false} otherwise.

*/
@Static(false)

public static boolean isPrivate(@Param int mod) {

return (mod & 0x00000002) != 0;

}
}
you should knowJava byAPIs
/**

* A helper class

* @see Class#getModifiers()

*

* @author Hendrik Ebbers
* @deprecated

*/
@Deprectaded
public class Helper {
@Important
private Logger logger = new Logger();
/**

* Return {@code true} if the integer argument includes the {@code private} modifier, {@code false} otherwise.

*

* @param mod a set of modifiers

* @return {@code true} if {@code mod} includes the {@code private} modifier; {@code false} otherwise.

*/
@Static(false)

public static boolean isPrivate(@Param int mod) {

return (mod & 0x00000002) != 0;

}
}
Annotations
you should knowJava byAPIs
/**

* A helper class

* @see Class#getModifiers()

*

* @author Hendrik Ebbers
* @deprecated

*/
@Deprectaded
public class Helper {
@Important
private Logger logger = new Logger();
/**

* Return {@code true} if the integer argument includes the {@code private} modifier, {@code false} otherwise.

*

* @param mod a set of modifiers

* @return {@code true} if {@code mod} includes the {@code private} modifier; {@code false} otherwise.

*/
@Static(false)

public static boolean isPrivate(@Param int mod) {

return (mod & 0x00000002) != 0;

}
}
Annotations
@Deprectated
annotation is defined
in the JRE
you should knowJava byAPIs
/**

* A helper class

* @see Class#getModifiers()

*

* @author Hendrik Ebbers
* @deprecated

*/
@Deprectaded
public class Helper {
@Important
private Logger logger = new Logger();
/**

* Return {@code true} if the integer argument includes the {@code private} modifier, {@code false} otherwise.

*

* @param mod a set of modifiers

* @return {@code true} if {@code mod} includes the {@code private} modifier; {@code false} otherwise.

*/
@Static(false)

public static boolean isPrivate(@Param int mod) {

return (mod & 0x00000002) != 0;

}
}
Annotations
the @Important annotation is not defined in
the JRE but it's easy to create your own
custom annotations (like @Autowired in
Spring)
you should knowJava byAPIs
/**

* A helper class

* @see Class#getModifiers()

*

* @author Hendrik Ebbers
* @deprecated

*/
@Deprectaded
public class Helper {
@Important
private Logger logger = new Logger();
/**

* Return {@code true} if the integer argument includes the {@code private} modifier, {@code false} otherwise.

*

* @param mod a set of modifiers

* @return {@code true} if {@code mod} includes the {@code private} modifier; {@code false} otherwise.

*/
@Static(false)

public static boolean isPrivate(@Param int mod) {

return (mod & 0x00000002) != 0;

}
}
Annotations
the @Static annotation is configured
by a boolean parameter
you should knowJava byAPIs
/**

* A helper class

* @see Class#getModifiers()

*

* @author Hendrik Ebbers
* @deprecated

*/
@Deprectaded
public class Helper {
@Important
private Logger logger = new Logger();
/**

* Return {@code true} if the integer argument includes the {@code private} modifier, {@code false} otherwise.

*

* @param mod a set of modifiers

* @return {@code true} if {@code mod} includes the {@code private} modifier; {@code false} otherwise.

*/
@Static(false)

public static boolean isPrivate(@Param int mod) {

return (mod & 0x00000002) != 0;

}
}
Annotations
the @Param annotation is another
custom annotation that is used to
annotate a method param
you should knowJava byAPIs
Annotations
• Annotations can be used to add metadata to
the code
• Annotations can be added to different points
of the code
• Annotation can be parametrable
• Custom annotations can be defined
you should knowJava byAPIs
Annotations
public @interface MyAnnotation {
}
you should knowJava byAPIs
Annotations
public @interface MyAnnotation {
}
access modifier name
annotation keyword
you should knowJava byAPIs
Annotations
@Documented
@Retention(RUNTIME)
@Target(METHOD)
public @interface MyAnnotation {
}
you should knowJava byAPIs
Annotations
@Documented
@Retention(RUNTIME)
@Target(METHOD)
public @interface MyAnnotation {
}
?
you should knowJava byAPIs
Annotations
@Documented
@Retention(RUNTIME)
@Target(ANNOTATION_TYPE)
public @interface Documented {
}
you should knowJava byAPIs
Annotations
• If an annotation is annotated with
@Documented the usage of the
annotation will be shown in JavaDoc
• The usage of @Documented has no
effect at runtime
you should knowJava byAPIs
Annotations
• The @Target annotation defines where
an annotation can be used.
• The enum ElementType defines all
supported types
you should knowJava byAPIs
Annotations
• TYPE
• FIELD
• METHOD
• PARAMETER
• CONSTRUCTOR
• LOCAL_VARIABLE
• ANNOTATION_TYPE
• PACKAGE
• TYPE_PARAMETER
• TYPE_USE[ ]
you should knowJava byAPIs
Annotations
@Target(METHOD)
public @interface MyAnnotation {
}
@MyAnnotation
public void sqrt(int value) {
return 1;
}
you should knowJava byAPIs
Annotations
@Target(METHOD)
public @interface MyAnnotation {
}
public void sqrt(@MyAnnotation int value) {
return 1;
}
you should knowJava byAPIs
Annotations
@Target(PARAMETER)
public @interface MyAnnotation {
}
public void sqrt(@MyAnnotation int value) {
return 1;
}
you should knowJava byAPIs
Annotations
@Target({PARAMETER, METHOD})
public @interface MyAnnotation {
}
@MyAnnotation
public void sqrt(@MyAnnotation int value) {
return 1;
}
you should knowJava byAPIs
Annotations
• The @Retention annotation defines
how long an annotation will be
retained.
• The enum RetentionPolicy defines all
supported types
you should knowJava byAPIs
Annotations
SOURCE CLASS RUNTIME
remove annotation at
compiletime
remove annotation at
runtime
do not remove
annotation
you should knowJava byAPIs
Annotations
SOURCE CLASS RUNTIME
general meta
information like
@Override
for example the
annotations of findbugs
All annotations that
are used at runtime
you should knowJava byAPIs
Annotations
• There are several ways how
annotations can be used
• Annotations like @Deprecated define
useful information for the developer
(IDE support) and compiler
you should knowJava byAPIs
Annotations
• Projects like Lombok use annotations
for annotation processing at compile
time
• Annotations like @Inject are used to
modify objects at runtime
you should knowJava byAPIs
Annotations
• All annotations that have a @Retention
policy that is defined as RUNTIME can
be accessed by using reflection.
• In general this is one of the tricks that
make DI or Spring work
you should knowJava byAPIs
Annotations
• How can I check for annotations in my
code at runtime
?
you should knowJava byAPIs
Annotations
Class cls = MyCustomClass.class;

boolean val = cls.isAnnotationPresent(MyAnnotation.class);
• Reflections ;)
you should knowJava byAPIs
Annotations
• Annotations can contain parameters
public @interface Column {
String name();
}
@Column(name="Description")
private String desc;
you should knowJava byAPIs
Annotations
• If an Annotations only needs one
param it should be named as "value"
• By doing so the name must not be
specified when using the annotation
you should knowJava byAPIs
Annotations
public @interface Column {
String value();
}
@Column("Name")
private String name;
you should knowJava byAPIs
Annotations
• Annotations can define a default value
for a parameters
public @interface Column {
String name() default "";
}
@Column
private String name;
you should knowJava byAPIs
Annotations
• Additional topics:
• @Inherited
• Lists of annotations
• Meta annotations
• Annotation Processor
Questions

Java ap is you should know

  • 1.
  • 2.
    by • Lead ofJUG Dortmund • JSR EG member • Java Developer @ Canoo Engineering AG • JavaOne Rockstar, Java Champion • I ❤ Star Wars www.guigarage.com@hendrikEbbers Hendrik Ebbers
  • 3.
  • 4.
  • 5.
  • 6.
    you should knowJavabyAPIs How to handle null blog.takipi.com
  • 7.
    you should knowJavabyAPIs How to handle null NullPointerException
  • 8.
    you should knowJavabyAPIs How to handle null • All of us have seen more than enough NullPointerExceptions • Java contains some APIs to tame the beast
  • 9.
    you should knowJavabyAPIs How to handle null • Before we try to avoid NPEs we should have a look how to handle null the right way • Java has null for a reason. Just use it.
  • 10.
    you should knowJavabyAPIs How to handle null public long getPeriode(final Date start, final Date end) { return end.getTime() - start.getTime(); } • This method is a typically bad example for NPEs / null values and how to deal with them • Do you have an idea why? ?
  • 11.
    you should knowJavabyAPIs How to handle null public long getPeriode(final Date start, final Date end) { return end.getTime() - start.getTime(); } Exception in thread "main" java.lang.NullPointerException at com.guigarage.sample.Example.getPeriode(Example.java:11) which date is null?
  • 12.
    you should knowJavabyAPIs How to handle null public Locale(String language, String country, String variant) {
 if (language== null || country == null || variant == null) {
 throw new NullPointerException();
 }
 . . .
 } JDK code . . .
  • 13.
    you should knowJavabyAPIs How to handle null/** * . . . * @throws NullPointerException if start or end is null */ public long getPeriode(final Date start, final Date end) { if(start == null) { throw new NullPointerException("start must not be null"); } if(end == null) { throw new NullPointerException("end must not be null"); } return end.getTime() - start.getTime(); }
  • 14.
    you should knowJavabyAPIs How to handle null /** * . . . * @throws NullPointerException if start or end is null */ public long getPeriode(final Date start, final Date end) { Objects.requireNonNull(start, "start must not be null"); Objects.requireNonNull(end, "end must not be null"); return end.getTime() - start.getTime(); }
  • 15.
    you should knowJavabyAPIs How to handle null • You should use it in constructors, too public class Periode { private final Date start; private final Date end; public Periode(final Date start, final Date end) { start = Objects.requireNonNull(start, "start must not be null"); end = Objects.requireNonNull(end, "end must not be null"); } }
  • 16.
    you should knowJavabyAPIs How to handle null • Make your own util methods public class MyUtils { public static <T> T requireNonNull(final T value, final String name) { return Objects.requireNonNull(value, name + " must not be null"); } }
  • 17.
    you should knowJavabyAPIs How to handle null • Sometime you don't want to throw a NPE • In that case the use of default values is an option
  • 18.
    you should knowJavabyAPIs How to handle null public boolean containsA(final String input) { String currentInput = input; if(currentInput == null) { currentInput = ""; } return currentInput.contains("A"); }
  • 19.
    you should knowJavabyAPIs How to handle null • Sometime you don't want to throw a NPE • In that case the use of default values is an option • Java 8 provides the Optional class to simplify this
  • 20.
    you should knowJavabyAPIs How to handle null public boolean containsA(final String input) { return Optional.ofNullable(input).orElse("").contains("A"); } create a new Optional that wraps a value returns the internal value or the given value if the internal value is null
  • 21.
    you should knowJavabyAPIs How to handle null • You can use Optional internally in your method logic • You can use Optional as a return value of a method • You should not use Optional as a param
  • 22.
    you should knowJavabyAPIs How to handle null public Optional<Entity> findByName(final String name) { Objects.requireNonNull(name, "name must not be null"); String query = "Select entity where name = " + name; return Optional.ofNullable(database.executeQuery(query)); } • This methods can be used as a starting point for a fluent API findByName("Java").ifPresent(entity -> table.add(entity));
  • 23.
    you should knowJavabyAPIs How to handle null • Another example that provides the id of an selected element maybe nothing is selected list shows "Movie" objects that provide title and id
  • 24.
    you should knowJavabyAPIs How to handle null final Integer selectedId = Optional.ofNullable(list.getSelected()) .map(i -> i.getId()) .orElse(null); • Another example that provides the id of an selected element
  • 25.
    you should knowJavabyAPIs How to handle null • Since autoboxing is a cool feature in general it sucks if you run in NPEs • Using Optional can help you to avoid this exceptions
  • 26.
    you should knowJavabyAPIs • Let's have a look at a bean -> entity converter
 
 
 
 What could possibly go wrong How to handle null public class MyBean { public Integer getCount(); } public class MyEntity { public void setCount(int c); } ?
  • 27.
    you should knowJavabyAPIs public class MyBean { public Integer getCount(); } How to handle null hint : this could return null public class MyEntity { public void setCount(int c); }
  • 28.
    you should knowJavabyAPIs public MyEntity convert(final MyBean bean) { Objects.requireNonNull(bean, "bean must not be null"); MyEntity entity = new MyEntity(); entity.setCount(bean.getCount()); return entity; } How to handle null might throw a NPE since we can't pass null as value for a primitive
  • 29.
    you should knowJavabyAPIs public MyEntity convert(final MyBean bean) { Objects.requireNonNull(bean, "bean must not be null"); MyEntity entity = new MyEntity(); entity.setCount(Optional.ofNullable(bean.getCount()).orElse(0)); return entity; } How to handle null default value
  • 30.
  • 31.
    you should knowJavabyAPIs Service Provider Interface • Based on Interfaces it's quite easy to define a general service and several implementations in Java
  • 32.
    you should knowJavabyAPIs Service Provider Interface public interface MathOperation { String getSign(); double calc(double valA, double valB); }
  • 33.
    you should knowJavabyAPIs Service Provider Interface • We can provide several implementations of math operations • AddOperation • SubstractOperation
  • 34.
    you should knowJavabyAPIs Service Provider Interface public class Multiply implements MathOperation { public String getSign() { return "*";} double calc(double valA, double valB){ return valA * valB; } }
  • 35.
    you should knowJavabyAPIs Service Provider Interface • Instances of the implementations can be accessed by using the general interface • All instances can simply be stored in a collection
  • 36.
    you should knowJavabyAPIs Service Provider Interface List<MathOperation> operations = new ArrayList<>(); operations.add(new MultipyOperation()); operations.add(new AddOperation()); operations.add(new DivideOperation()); operations.add(new SubstractOperation()); operations.forEach(o -> { System.out.println("Supported Operation: " + o.getSign()); });
  • 37.
    you should knowJavabyAPIs Service Provider Interface • With Java 8 default methods we can even define default logic for some parts of the service • Use defaults only if it really makes sense!
  • 38.
    you should knowJavabyAPIs Service Provider Interface public interface MathOperation { String getSign(); double calc(double valA, double valB); default String getHelp() { return "No help text for sign" + getSign(); } }
  • 39.
    you should knowJavabyAPIs Service Provider Interface • Let's think about a bigger application • Often based on several modules / jars • Several jars contains several service implementations
  • 40.
    you should knowJavabyAPIs Service Provider Interface Application Basic Math Module Math Def Module Special Math Module contains the interface
  • 41.
    you should knowJavabyAPIs Service Provider Interface Application Basic Math Module Math Def Module Special Math Module contains the interface contains implementations contains implementations
  • 42.
    you should knowJavabyAPIs Service Provider Interface Application Basic Math Module Math Def Module Special Math Module contains the interface contains implementations contains implementations use implementations
  • 43.
    you should knowJavabyAPIs Service Provider Interface Application Basic Math Module Math Def Module Special Math Module depends on depends on depends ondepends on
  • 44.
    you should knowJavabyAPIs Service Provider Interface Application Basic Math Module Math Def Module Special Math Module One Million Dollar Question
  • 45.
    you should knowJavabyAPIs Service Provider Interface • Where should we define the following method? public List<MathOperation> getAllImplInClasspath(); ?
  • 46.
    you should knowJavabyAPIs Service Provider Interface • We can't define it in the "Math Def Module" since this module has no dependency to any implementation • Method would return
 an empty list
  • 47.
    you should knowJavabyAPIs Service Provider Interface • We can't define it in the "Basic Math" or the "Special Math" since this modules don't know all implementations. • Method would not
 return all 
 implementations
  • 48.
    you should knowJavabyAPIs Service Provider Interface • Only the "Application" module knows all implementations since it's the only module that depends on all other modules
  • 49.
    you should knowJavabyAPIs Service Provider Interface Basic Math Module Math Def Module Special Math Module Algebra Math Module Geometry Math Module • Let's add some complexity
  • 50.
    you should knowJavabyAPIs Service Provider Interface Customer A Application Basic Math Module Math Def Module Special Math Module Algebra Math Module Geometry Math Module Customer B Application Customer C Application
  • 51.
    you should knowJavabyAPIs Service Provider Interface • We don't want to implement the
 
 for each application • We need something new that loads all implementations dynamically public List<MathOperation> getAllImplInClasspath();
  • 52.
    you should knowJavabyAPIs Service Provider Interface • Service Provider Interface (SPI) provides a simple API to solve this issue • Could be used to create a minimal but powerful Plug In API
  • 53.
    you should knowJavabyAPIs Service Provider Interface • Start by creating an interface public interface MathOperation { String getSign(); double calc(double valA, double valB); } we already have it
  • 54.
    you should knowJavabyAPIs Service Provider Interface • Each module that provides implementations of the interface most provide a service file • File must be located under META-INF/ services/
  • 55.
    you should knowJavabyAPIs Service Provider Interface • Name of the file must be equals to the interface name META-INF/services/com.canoo.math.MathOperation file name
  • 56.
    you should knowJavabyAPIs Service Provider Interface • File simply contains names of all implementations com.canoo.basic.AddOperation
 com.canoo.basic.MinusOperation define one implementation per line
  • 57.
    you should knowJavabyAPIs Service Provider Interface • The Service Provider Interface (SPI) will automatically find all implementations at runtime • Instances of the classes will automatically be created • Default constructor is needed
  • 58.
    you should knowJavabyAPIs Service Provider Interface • You can simply iterate over all implementations Iterator<MathOperation> iterator = ServiceLoader.load(MathOperation.class).iterator(); 
 while (iterator.hasNext()) {
 MathOperation operation = iterator.next();
 }
  • 59.
    you should knowJavabyAPIs Service Provider Interface • At the end we can implement the
 
 method simple in the "Math Def Module" • The service provider 
 will automatically find
 all implementations public List<MathOperation> getAllImplInClasspath();
  • 60.
  • 61.
    you should knowJavabyAPIs Annotations • Let's start with a quiz :) • How many Java annotations are used in the code? ?
  • 62.
    you should knowJavabyAPIs Annotations/**
 * A helper class
 * @see Class#getModifiers()
 *
 * @author Hendrik Ebbers * @deprecated
 */ @Deprectaded public class Helper { @Important private Logger logger = new Logger(); /**
 * Return {@code true} if the integer argument includes the {@code private} modifier, {@code false} otherwise.
 *
 * @param mod a set of modifiers
 * @return {@code true} if {@code mod} includes the {@code private} modifier; {@code false} otherwise.
 */ @Static(false)
 public static boolean isPrivate(@Param int mod) {
 return (mod & 0x00000002) != 0;
 } }
  • 63.
    you should knowJavabyAPIs /**
 * A helper class
 * @see Class#getModifiers()
 *
 * @author Hendrik Ebbers * @deprecated
 */ @Deprectaded public class Helper { @Important private Logger logger = new Logger(); /**
 * Return {@code true} if the integer argument includes the {@code private} modifier, {@code false} otherwise.
 *
 * @param mod a set of modifiers
 * @return {@code true} if {@code mod} includes the {@code private} modifier; {@code false} otherwise.
 */ @Static(false)
 public static boolean isPrivate(@Param int mod) {
 return (mod & 0x00000002) != 0;
 } } Annotations
  • 64.
    you should knowJavabyAPIs /**
 * A helper class
 * @see Class#getModifiers()
 *
 * @author Hendrik Ebbers * @deprecated
 */ @Deprectaded public class Helper { @Important private Logger logger = new Logger(); /**
 * Return {@code true} if the integer argument includes the {@code private} modifier, {@code false} otherwise.
 *
 * @param mod a set of modifiers
 * @return {@code true} if {@code mod} includes the {@code private} modifier; {@code false} otherwise.
 */ @Static(false)
 public static boolean isPrivate(@Param int mod) {
 return (mod & 0x00000002) != 0;
 } } Annotations @Deprectated annotation is defined in the JRE
  • 65.
    you should knowJavabyAPIs /**
 * A helper class
 * @see Class#getModifiers()
 *
 * @author Hendrik Ebbers * @deprecated
 */ @Deprectaded public class Helper { @Important private Logger logger = new Logger(); /**
 * Return {@code true} if the integer argument includes the {@code private} modifier, {@code false} otherwise.
 *
 * @param mod a set of modifiers
 * @return {@code true} if {@code mod} includes the {@code private} modifier; {@code false} otherwise.
 */ @Static(false)
 public static boolean isPrivate(@Param int mod) {
 return (mod & 0x00000002) != 0;
 } } Annotations the @Important annotation is not defined in the JRE but it's easy to create your own custom annotations (like @Autowired in Spring)
  • 66.
    you should knowJavabyAPIs /**
 * A helper class
 * @see Class#getModifiers()
 *
 * @author Hendrik Ebbers * @deprecated
 */ @Deprectaded public class Helper { @Important private Logger logger = new Logger(); /**
 * Return {@code true} if the integer argument includes the {@code private} modifier, {@code false} otherwise.
 *
 * @param mod a set of modifiers
 * @return {@code true} if {@code mod} includes the {@code private} modifier; {@code false} otherwise.
 */ @Static(false)
 public static boolean isPrivate(@Param int mod) {
 return (mod & 0x00000002) != 0;
 } } Annotations the @Static annotation is configured by a boolean parameter
  • 67.
    you should knowJavabyAPIs /**
 * A helper class
 * @see Class#getModifiers()
 *
 * @author Hendrik Ebbers * @deprecated
 */ @Deprectaded public class Helper { @Important private Logger logger = new Logger(); /**
 * Return {@code true} if the integer argument includes the {@code private} modifier, {@code false} otherwise.
 *
 * @param mod a set of modifiers
 * @return {@code true} if {@code mod} includes the {@code private} modifier; {@code false} otherwise.
 */ @Static(false)
 public static boolean isPrivate(@Param int mod) {
 return (mod & 0x00000002) != 0;
 } } Annotations the @Param annotation is another custom annotation that is used to annotate a method param
  • 68.
    you should knowJavabyAPIs Annotations • Annotations can be used to add metadata to the code • Annotations can be added to different points of the code • Annotation can be parametrable • Custom annotations can be defined
  • 69.
    you should knowJavabyAPIs Annotations public @interface MyAnnotation { }
  • 70.
    you should knowJavabyAPIs Annotations public @interface MyAnnotation { } access modifier name annotation keyword
  • 71.
    you should knowJavabyAPIs Annotations @Documented @Retention(RUNTIME) @Target(METHOD) public @interface MyAnnotation { }
  • 72.
    you should knowJavabyAPIs Annotations @Documented @Retention(RUNTIME) @Target(METHOD) public @interface MyAnnotation { } ?
  • 73.
    you should knowJavabyAPIs Annotations @Documented @Retention(RUNTIME) @Target(ANNOTATION_TYPE) public @interface Documented { }
  • 74.
    you should knowJavabyAPIs Annotations • If an annotation is annotated with @Documented the usage of the annotation will be shown in JavaDoc • The usage of @Documented has no effect at runtime
  • 75.
    you should knowJavabyAPIs Annotations • The @Target annotation defines where an annotation can be used. • The enum ElementType defines all supported types
  • 76.
    you should knowJavabyAPIs Annotations • TYPE • FIELD • METHOD • PARAMETER • CONSTRUCTOR • LOCAL_VARIABLE • ANNOTATION_TYPE • PACKAGE • TYPE_PARAMETER • TYPE_USE[ ]
  • 77.
    you should knowJavabyAPIs Annotations @Target(METHOD) public @interface MyAnnotation { } @MyAnnotation public void sqrt(int value) { return 1; }
  • 78.
    you should knowJavabyAPIs Annotations @Target(METHOD) public @interface MyAnnotation { } public void sqrt(@MyAnnotation int value) { return 1; }
  • 79.
    you should knowJavabyAPIs Annotations @Target(PARAMETER) public @interface MyAnnotation { } public void sqrt(@MyAnnotation int value) { return 1; }
  • 80.
    you should knowJavabyAPIs Annotations @Target({PARAMETER, METHOD}) public @interface MyAnnotation { } @MyAnnotation public void sqrt(@MyAnnotation int value) { return 1; }
  • 81.
    you should knowJavabyAPIs Annotations • The @Retention annotation defines how long an annotation will be retained. • The enum RetentionPolicy defines all supported types
  • 82.
    you should knowJavabyAPIs Annotations SOURCE CLASS RUNTIME remove annotation at compiletime remove annotation at runtime do not remove annotation
  • 83.
    you should knowJavabyAPIs Annotations SOURCE CLASS RUNTIME general meta information like @Override for example the annotations of findbugs All annotations that are used at runtime
  • 84.
    you should knowJavabyAPIs Annotations • There are several ways how annotations can be used • Annotations like @Deprecated define useful information for the developer (IDE support) and compiler
  • 85.
    you should knowJavabyAPIs Annotations • Projects like Lombok use annotations for annotation processing at compile time • Annotations like @Inject are used to modify objects at runtime
  • 86.
    you should knowJavabyAPIs Annotations • All annotations that have a @Retention policy that is defined as RUNTIME can be accessed by using reflection. • In general this is one of the tricks that make DI or Spring work
  • 87.
    you should knowJavabyAPIs Annotations • How can I check for annotations in my code at runtime ?
  • 88.
    you should knowJavabyAPIs Annotations Class cls = MyCustomClass.class;
 boolean val = cls.isAnnotationPresent(MyAnnotation.class); • Reflections ;)
  • 89.
    you should knowJavabyAPIs Annotations • Annotations can contain parameters public @interface Column { String name(); } @Column(name="Description") private String desc;
  • 90.
    you should knowJavabyAPIs Annotations • If an Annotations only needs one param it should be named as "value" • By doing so the name must not be specified when using the annotation
  • 91.
    you should knowJavabyAPIs Annotations public @interface Column { String value(); } @Column("Name") private String name;
  • 92.
    you should knowJavabyAPIs Annotations • Annotations can define a default value for a parameters public @interface Column { String name() default ""; } @Column private String name;
  • 93.
    you should knowJavabyAPIs Annotations • Additional topics: • @Inherited • Lists of annotations • Meta annotations • Annotation Processor
  • 94.