SlideShare a Scribd company logo
Java
Tips, Tricks and Pitfalls
KISS - Keep it Short and Simple!
KISS - Example 1 (Read properties from file)
Example of properties file:
hibernate.connection.username=myuser
hibernate.connection.password=secret
hibernate.c3p0.min_size=5
hibernate.c3p0.max_size=20
hibernate.c3p0.timeout=1800
hibernate.c3p0.max_statements=50
KISS - Example 1 (Implementation)
Overthinking
Elegance
Laziness
Experience
VS
KISS - Example 1 (Overthinking)
Let’s create a method with really self-describing name!
public Properties readAllLinesFromFileAndReturnPropertiesObject(File file) {
Properties properties = null;
// logic will be here
return properties;
}
KISS - Example 1 (Elegance)
Let’s create a method with really self-describing name!
public Properties readProperties(String filename) {
Properties properties = null;
// logic will be here
return properties;
}
KISS - Example 1 (Overthinking)
Let’s read the file and fill the properties!
BufferedReader bufferedReaderForFileWhichShouldContainsLines = new BufferedReader(
new InputStreamReader(new BufferedInputStream(new FileInputStream(file)))
);
String accumulatorForLineFromFile = null; properties = new Properties();
while ((accumulatorForLineFromFile = brffwhcl.readLine()) != null)
{
properties.setProperty(accumulatorForLineFromFile.split("=")[0],
accumulatorForLineFromFile.split("=")[1]);
}
KISS - Example 1 (Experience)
Let’s read the file and fill the properties!
public Properties readProperties(String filename) {
Properties properties = new Properties();
properties.load(new FileInputStream(filename));
return properties;
}
KISS - Example 1 (Overthinking)
Let’s handle some exceptions!
public Properties readAllLinesFromFileAndReturnPropertiesObject(File file) {
Properties properties = null;
if (file != null) {
...
} else {
throw new IllegalArgumentException("file which should contains all needed information "
+
"to init Properties object is null, that means that Java can't work with it, "
+
"please check your code and make sure that you are passing valid arguments",
new NullPointerException()
);
}
return properties;
}
KISS - Example 1 (Overthinking)
And several more...
public Properties readAllLinesFromFileAndReturnPropertiesObject(File file) {
Properties properties = null;
if (file != null) {
if (file.exists()) {
if (file.canRead()) {
try {
BufferedReader
bufferedReaderForFileWhichShouldContainsLines = new BufferedReader(
new InputStreamReader(
new BufferedInputStream(
new FileInputStream(file)
)
)
);
try {
String accumulatorForLineFromFile = null;
properties = new Properties();
while ((accumulatorForLineFromFile
=
bufferedReaderForFileWhichShouldContainsLines.readLine()) != null) {
properties.setProperty(
accumulatorForLineFromFile.split("=")[0],
accumulatorForLineFromFile.split("=")[1]
);
}
} catch (IOException ioException) {
throw new IllegalArgumentException("file which should contains all needed information "
+
"to init Properties object is not null, but it isn't suitable for reading, " +
"that means that Java can't work with it, " +
"please check your code and make sure that you are passing valid arguments",
new IOException(ioException)
);
} finally {
try {
bufferedReaderForFileWhichShouldContainsLines.close();
} catch (IOException ioException) {
System.err.printf("Can't close bufferedReaderForFileWhichShouldContainsLines: %s",
ioException.getMessage()
);
}
}
} catch (FileNotFoundException fileNotFoundException) {
throw new IllegalArgumentException("file which should contains all needed information " +
"to init Properties object is not null, but it not found, " +
"that means that Java can't work with it, " +
"please check your code and make sure that you are passing valid arguments",
new FileNotFoundException(fileNotFoundException.getMessage())
);
}
} else {
throw new IllegalArgumentException("file which should contains all needed information " +
"to init Properties object is not null, but it now unreadable, " +
"that means that Java can't work with it, " +
"please check your code and make sure that you are passing valid arguments",
new IllegalAccessException()
);
}
} else {
throw new IllegalArgumentException("file which should contains all needed information " +
"to init Properties object is not null, but it isn't exists, " +
"that means that Java can't work with it, " +
"please check your code and make sure that you are passing valid arguments",
new IllegalAccessException()
);
}
} else {
throw new IllegalArgumentException("file which should contains all needed information " +
"to init Properties object is null, that means that Java can't work with it, " +
"please check your code and make sure that you are passing valid arguments",
new NullPointerException()
);
}
return properties;
}
KISS - Example 1 (Laziness)
Let’s handle some exceptions!
public Properties readProperties(String filename) throws IOException {
Properties properties = new Properties();
properties.load(new FileInputStream(filename));
return properties;
}
Naming best & bad practices
Programming routine:
Naming best & bad practices
Programming routine:
Naming best practices
● Keep all names close to context and self-describing
○ But avoid “secret knowledge”
○ Share the context via javadoc or comments
Naming best practices
● Keep all names close to context and self-describing
○ But avoid “secret knowledge”
○ Share the context via javadoc or comments
● Variable type should be obvious
○ That doesn’t mean that name should contain Type
Naming best practices
● Keep all names close to context and self-describing
○ But avoid “secret knowledge”
○ Share the context via javadoc or comments
● Variable type should be obvious
○ That doesn’t mean that name should contain Type
● Boolean variables/methods names should be suitable
for the sentence: “if <variable_name> then ...?”
Naming best practices
● Keep all names close to context and self-describing
○ But avoid “secret knowledge”
○ Share the context via javadoc or comments
● Variable type should be obvious
○ That doesn’t mean that name should contain Type
● Boolean variables/methods names should be suitable
for the sentence: “if <variable_name> then ...?”
● Methods names should answer the question “what to do?”
Naming best practices
● Keep all names close to context and self-describing
○ But avoid “secret knowledge”
○ Share the context via javadoc or comments
● Variable type should be obvious
○ That doesn’t mean that name should contain Type
● Boolean variables/methods names should be suitable
for the sentence: “if <variable_name> then ...?”
● Methods names should answer the question “what to do?”
● Type names might contain parent names
Naming bad practices
Naming bad practices
● Using words that means nothing: obj, data, value, tmp...
a. There is always place for exceptions
Naming bad practices
● Using words that means nothing: obj, data, value, tmp...
a. There is always place for exceptions
● Fake/Wrong variable type
a. This might cost a burned chair...
Naming bad practices
● Using words that means nothing: obj, data, value, tmp...
a. There is always place for exceptions
● Fake/Wrong variable type
a. This might cost a burned chair...
● Single-character names: w, t, f ... o, m, g
a. Especially without any context - 100% burned chair
Naming bad practices
● Using words that means nothing: obj, data, value, tmp...
a. There is always place for exceptions
● Fake/Wrong variable type
a. This might cost a burned chair...
● Single-character names: w, t, f ... o, m, g
a. Especially without any context - 100% burned chair
● Fake/Incomplete names of the methods
Naming bad practices
● Using words that means nothing: obj, data, value, tmp...
a. There is always place for exceptions
● Fake/Wrong variable type
a. This might cost a burned chair...
● Single-character names: w, t, f ... o, m, g
a. Especially without any context - 100% burned chair
● Fake/Incomplete names of the methods
● Public argument names based on secret knowledge
a. Especially without any context - 200% burned chair
Dirty and Pure methods
Hello, my name is side-effect...
public int[] sortArray(int[] array) {
Arrays.sort(array);
return array;
}
Dirty and Pure methods
And sometimes I’m not obvious at all…
public <T> T[] sortArray(T[] array) {
if (array == null || array.length < 2) return array;
Comparator<T> comparator = null;
T[] tmpArray = checkAndReturnArray(array);
T notNullElement = null;
for (int i = 0; i < tmpArray.length && notNullElement == null; notNullElement = tmpArray[i++]) ;
if (notNullElement == null) return array;
if (notNullElement instanceof Comparator) { comparator = (Comparator<T>) notNullElement; }
else if (notNullElement instanceof Comparable) {
comparator = (o1, o2) -> {
if (o1 == null) return 1; if (o2 == null) return -1; return ((Comparable<T>) o1).compareTo(o2);
};
}
if (comparator == null) return array;
Arrays.sort(tmpArray, comparator);
return tmpArray;
}
Dirty and Pure methods
Here's Johnny!
/**
* Checks array and returns copy if Mars is in the zenith of Saturn
*/
public <T> T[] checkAndReturnArray(T[] array) {
return (array != null)
? ((System.currentTimeMillis() > (42 * 64 * 30 * 365))
? ((System.getenv("magic") == null)
? array : null) : array) : null;
}
Dirty and Pure methods
Here's Johnny!
/**
* Checks array and returns copy if Mars is in the zenith of Saturn
*/
public <T> T[] checkAndReturnArray(T[] array) {
return (array != null)
? ((System.currentTimeMillis() > (42 * 64 * 30 * 365))
? ((System.getenv("magic") == null)
? array : null) : array) : null;
}
Immutability and final keyword
If you can’t change the methods,
you can change the arguments...
Immutability and final keyword
What is immutability?
class Immutable {
private final String immutableField;
public Immutable(String immutableField) {
this.immutableField = immutableField;
}
public String getImmutableField() {
return immutableField;
}
}
Examples:
String, Integer, File, URL...
Immutability and final keyword
What is immutability?
class Immutable {
private final String immutableField;
public Immutable(String immutableField) {
this.immutableField = immutableField;
}
public String getImmutableField() {
return immutableField;
}
}
Examples:
String, Integer, File, URL...
What is mutability?
class Mutable {
private List<String> mutableField;
public List<String> getMutableField() {
return mutableField;
}
public void setMutableField(List<String> mutableField) {
this.mutableField = mutableField;
}
}
Examples:
ArrayList, Arrays, StringBuilder...
Immutability and final keyword
Why immutability is good?
● Preventing side-effects
● Thread-safe
● Easy to debug
● Easy to implement
● Easy to extend
● Easy to scale
Immutability and final keyword
Why immutability is good?
● Preventing side-effects
● Thread-safe
● Easy to debug
● Easy to implement
● Easy to extend
● Easy to scale
Why immutability is bad?
● Real world isn’t immutable
● Constraints you
● Not always convenient
● Increases memory usage
● Performance degradation
● There is always will be an
exception...
Immutability and final keyword
Keyword final can be used with:
● Variables
○ final Object someField;
Immutability and final keyword
Keyword final can be used with:
● Variables
○ final Object someField;
● Methods
○ final public void someMethod() { ... }
○ public void someMethod(final Object argument) { ... }
Immutability and final keyword
Keyword final can be used with:
● Variables
○ final Object someField;
● Methods
○ final public void someMethod() { ... }
○ public void someMethod(final Object argument) { ... }
● Classes
○ public final class Example3;
try-catch-finally pitfalls
Simple puzzle?
public static int puzzle() {
try {
return 5;
} catch (Exception ex) {
return 10;
} finally {
return 15;
}
}
try-catch-finally pitfalls
Simple puzzle?
public static int puzzle() {
try {
return 5;
} catch (Exception ex) {
return 10;
} finally {
return 15;
}
}
try-catch-finally pitfalls
try pitfalls
● It’s a new scope…
● Each line might raise exception
● catch or finally is required
● Try with resources?
○ Custom AutoCloseable implementation
○ Implicit side-effect
try-catch-finally pitfalls
catch pitfalls
● It’s a new scope…
● Type erasing
● Performance degradation
● Exception-oriented logic
try-catch-finally pitfalls
finally pitfalls
● It’s a new scope…
● WILL BE EXECUTED ALWAYS!!!
○ Except for that moment, in which you will really need this...
● Might cause performance degradation
● Newer return value in finally
○ But sometimes...
Early exception handling
Exception handling
public int someMethod(String arg1, String arg2) {
final int defaultValue = 42;
int value = 0;
try {
int int1 = Integer.parseInt(arg1);
int int2 = Integer.parseInt(arg2);
value = int1 / int2;
} catch (Exception ex) {
System.err.println(ex);
return defaultValue;
}
return value;
}
Early exception handling
Exception handling
public int someMethod(String arg1, String arg2) {
final int defaultValue = 42;
int value = 0;
try {
int int1 = Integer.parseInt(arg1);
int int2 = Integer.parseInt(arg2);
value = int1 / int2;
} catch (Exception ex) {
System.err.println(ex);
return defaultValue;
}
return value;
}
Early exception handling
public int someMethod(String arg1, String arg2) {
final int defaultValue = 42;
if (notNumber(arg1) || notNumber(arg2)) {
return defaultValue;
}
int int1 = Integer.parseInt(arg1);
int int2 = Integer.parseInt(arg2);
if (int2 == 0) {
return defaultValue;
}
int value = int1 / int2;
return value;
}
Early exception handling
● Objects.requireNonNull(argument); (throw early)
Early exception handling
● Objects.requireNonNull(argument); (throw early)
● Use IllegalArgumentException() (throw early)
Early exception handling
● Objects.requireNonNull(argument); (throw early)
● Use IllegalArgumentException() (throw early)
● Use UnsupportedOperationException() (throw early)
Early exception handling
● Objects.requireNonNull(argument); (throw early)
● Use IllegalArgumentException() (throw early)
● Use UnsupportedOperationException() (throw early)
● Delegate exception handling, use throws (catch late)
Early exception handling
● Objects.requireNonNull(argument); (throw early)
● Use IllegalArgumentException() (throw early)
● Use UnsupportedOperationException() (throw early)
● Delegate exception handling, use throws (catch late)
● Write javadoc
● Write logs
Why null is bad?
● More than 2500 NPE defects in our Jira
Why null is bad?
● More than 2500 NPE defects in our Jira
● null is low-level concept
Why null is bad?
● More than 2500 NPE defects in our Jira
● null is low-level concept
● Zero information
Why null is bad?
● More than 2500 NPE defects in our Jira
● null is low-level concept
● Zero information
● null instanceof Type --> false
Why null is bad?
● More than 2500 NPE defects in our Jira
● null is low-level concept
● Zero information
● null instanceof Type --> false
● int value = (Integer) null; --> NPE
Why null is bad?
● More than 2500 NPE defects in our Jira
● null is low-level concept
● Zero information
● null instanceof Type --> false
● int value = (Integer) null; --> NPE
● Many methods uses .toString() --> NPE
○ String.valueOf(obj) - solves this issue
Why null is bad?
● More than 2500 NPE defects in our Jira
● null is low-level concept
● Zero information
● null instanceof Type --> false
● int value = (Integer) null; --> NPE
● Many methods uses .toString() --> NPE
○ String.valueOf(obj) - solves this issue
● Null-oriented programming is legacy
○ Use Optional<T> instead
Lean refactoring
● Don’t broke tests (Red-Green-Refactor)
Lean refactoring
● Don’t broke tests (Red-Green-Refactor)
● Don’t change signatures
Lean refactoring
● Don’t broke tests (Red-Green-Refactor)
● Don’t change signatures
● Don’t change parameters order
○ Especially for constructors
Lean refactoring
● Don’t broke tests (Red-Green-Refactor)
● Don’t change signatures
● Don’t change parameters order
○ Especially for constructors
● Don’t change contract
Lean refactoring
● Don’t broke tests (Red-Green-Refactor)
● Don’t change signatures
● Don’t change parameters order
○ Especially for constructors
● Don’t change contract
● Use @Deprecated
Abusing Java
Just because you can, it doesn’t mean you should...
● Use enum as Singleton
Abusing Java
Just because you can, it doesn’t mean you should...
● Use enum as Singleton
● Use static as Singleton
Abusing Java
Just because you can, it doesn’t mean you should...
● Use enum as Singleton
● Use static as Singleton
● Use reflection
○ Especially for internal JDK classes
Abusing Java
Just because you can, it doesn’t mean you should...
● Use enum as Singleton
● Use static as Singleton
● Use reflection
○ Especially for internal JDK classes
● Use interface just because of signature
Abusing Java
Just because you can, it doesn’t mean you should...
● Use enum as Singleton
● Use static as Singleton
● Use reflection
○ Especially for internal JDK classes
● Use interface just because of signature
● Use inheritance as aggregation/delegation
Abusing Java
Just because you can, it doesn’t mean you should...
● Use enum as Singleton
● Use static as Singleton
● Use reflection
○ Especially for internal JDK classes
● Use interface just because of signature
● Use inheritance as aggregation/delegation
● ...
● If it works, it doesn’t mean it’s good.
SOLID in the nutshell
● S - Single responsibility
SOLID in the nutshell
● S - Single responsibility
● O - Opened for extension, but closed for changes
SOLID in the nutshell
● S - Single responsibility
● O - Opened for extension, but closed for changes
● L - Liskov substitution, children should keep parents
contracts.
SOLID in the nutshell
● S - Single responsibility
● O - Opened for extension, but closed for changes
● L - Liskov substitution, children should keep parents
contracts.
● I - Interface segregation is better than God-interface.
SOLID in the nutshell
● S - Single responsibility
● O - Opened for extension, but closed for changes
● L - Liskov substitution, children should keep parents
contracts.
● I - Interface segregation is better than God-interface.
● D - Dependency inversion, build dependencies over
abstractions, not over implementations.
Q&A Session (the end)
Attention!
Thanks for your attention!

More Related Content

PDF
Ruby_Basic
PDF
Lambda? You Keep Using that Letter
PPTX
Ruby object model - Understanding of object play role for ruby
PPT
The ruby programming language
PPTX
Ruby basics
PDF
Ruby — An introduction
PDF
Introduction to Ruby Programming Language
PDF
Python Part 2
Ruby_Basic
Lambda? You Keep Using that Letter
Ruby object model - Understanding of object play role for ruby
The ruby programming language
Ruby basics
Ruby — An introduction
Introduction to Ruby Programming Language
Python Part 2

What's hot (20)

ODP
Functional Objects & Function and Closures
PDF
Python Part 1
PPTX
Erlang kickstart
PPT
Java
PPTX
Code Like Pythonista
PDF
NSCoder Swift - An Introduction to Swift
PPTX
Oop in-php
PDF
Scala: A brief tutorial
PDF
Everything is Permitted: Extending Built-ins
PPTX
Object oriented concepts
PPTX
Design patterns(red)
PDF
Real world gobbledygook
PPT
Class 7 - PHP Object Oriented Programming
PPT
Class and Objects in PHP
PDF
iPhone Seminar Part 2
PPT
Oops in PHP
PPTX
Introduction to javascript and yoolkui
PDF
7 Sins of Java fixed in Kotlin
KEY
Xtext Eclipse Con
Functional Objects & Function and Closures
Python Part 1
Erlang kickstart
Java
Code Like Pythonista
NSCoder Swift - An Introduction to Swift
Oop in-php
Scala: A brief tutorial
Everything is Permitted: Extending Built-ins
Object oriented concepts
Design patterns(red)
Real world gobbledygook
Class 7 - PHP Object Oriented Programming
Class and Objects in PHP
iPhone Seminar Part 2
Oops in PHP
Introduction to javascript and yoolkui
7 Sins of Java fixed in Kotlin
Xtext Eclipse Con
Ad

Similar to Java Tips, Tricks and Pitfalls (20)

PPT
JAVA Tutorial- Do's and Don'ts of Java programming
PPT
JAVA Tutorial- Do's and Don'ts of Java programming
ODP
Dynamic Python
PDF
Exploring Ceylon with Gavin King - JUG BB Talk - Belrin 2014
PPT
Ruby For Java Programmers
PPTX
Python Workshop - Learn Python the Hard Way
PDF
Lazy Java
PDF
Lazy Java
PDF
Lazy java
PDF
Mario Fusco - Lazy Java - Codemotion Milan 2018
PPTX
“Insulin” for Scala’s Syntactic Diabetes
PDF
Ceylon idioms by Gavin King
PDF
Write codeforhumans
PPTX
Ruby Basics
PPTX
Practically Functional
PPTX
02 - Prepcode
PPT
Scala - brief intro
PPT
name name2 n2.ppt
PPT
ppt2
PPT
name name2 n
JAVA Tutorial- Do's and Don'ts of Java programming
JAVA Tutorial- Do's and Don'ts of Java programming
Dynamic Python
Exploring Ceylon with Gavin King - JUG BB Talk - Belrin 2014
Ruby For Java Programmers
Python Workshop - Learn Python the Hard Way
Lazy Java
Lazy Java
Lazy java
Mario Fusco - Lazy Java - Codemotion Milan 2018
“Insulin” for Scala’s Syntactic Diabetes
Ceylon idioms by Gavin King
Write codeforhumans
Ruby Basics
Practically Functional
02 - Prepcode
Scala - brief intro
name name2 n2.ppt
ppt2
name name2 n
Ad

Recently uploaded (20)

PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PPTX
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
PDF
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
PPTX
Reimagine Home Health with the Power of Agentic AI​
PDF
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
PDF
Product Update: Alluxio AI 3.7 Now with Sub-Millisecond Latency
PPTX
Why Generative AI is the Future of Content, Code & Creativity?
PDF
Digital Systems & Binary Numbers (comprehensive )
PPTX
assetexplorer- product-overview - presentation
PPTX
history of c programming in notes for students .pptx
PDF
Softaken Excel to vCard Converter Software.pdf
PDF
Designing Intelligence for the Shop Floor.pdf
PDF
Adobe Illustrator 28.6 Crack My Vision of Vector Design
PDF
Design an Analysis of Algorithms II-SECS-1021-03
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
PPTX
L1 - Introduction to python Backend.pptx
PDF
top salesforce developer skills in 2025.pdf
PPTX
Log360_SIEM_Solutions Overview PPT_Feb 2020.pptx
PDF
Odoo Companies in India – Driving Business Transformation.pdf
PDF
wealthsignaloriginal-com-DS-text-... (1).pdf
How to Choose the Right IT Partner for Your Business in Malaysia
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
Reimagine Home Health with the Power of Agentic AI​
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
Product Update: Alluxio AI 3.7 Now with Sub-Millisecond Latency
Why Generative AI is the Future of Content, Code & Creativity?
Digital Systems & Binary Numbers (comprehensive )
assetexplorer- product-overview - presentation
history of c programming in notes for students .pptx
Softaken Excel to vCard Converter Software.pdf
Designing Intelligence for the Shop Floor.pdf
Adobe Illustrator 28.6 Crack My Vision of Vector Design
Design an Analysis of Algorithms II-SECS-1021-03
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
L1 - Introduction to python Backend.pptx
top salesforce developer skills in 2025.pdf
Log360_SIEM_Solutions Overview PPT_Feb 2020.pptx
Odoo Companies in India – Driving Business Transformation.pdf
wealthsignaloriginal-com-DS-text-... (1).pdf

Java Tips, Tricks and Pitfalls

  • 2. KISS - Keep it Short and Simple!
  • 3. KISS - Example 1 (Read properties from file) Example of properties file: hibernate.connection.username=myuser hibernate.connection.password=secret hibernate.c3p0.min_size=5 hibernate.c3p0.max_size=20 hibernate.c3p0.timeout=1800 hibernate.c3p0.max_statements=50
  • 4. KISS - Example 1 (Implementation) Overthinking Elegance Laziness Experience VS
  • 5. KISS - Example 1 (Overthinking) Let’s create a method with really self-describing name! public Properties readAllLinesFromFileAndReturnPropertiesObject(File file) { Properties properties = null; // logic will be here return properties; }
  • 6. KISS - Example 1 (Elegance) Let’s create a method with really self-describing name! public Properties readProperties(String filename) { Properties properties = null; // logic will be here return properties; }
  • 7. KISS - Example 1 (Overthinking) Let’s read the file and fill the properties! BufferedReader bufferedReaderForFileWhichShouldContainsLines = new BufferedReader( new InputStreamReader(new BufferedInputStream(new FileInputStream(file))) ); String accumulatorForLineFromFile = null; properties = new Properties(); while ((accumulatorForLineFromFile = brffwhcl.readLine()) != null) { properties.setProperty(accumulatorForLineFromFile.split("=")[0], accumulatorForLineFromFile.split("=")[1]); }
  • 8. KISS - Example 1 (Experience) Let’s read the file and fill the properties! public Properties readProperties(String filename) { Properties properties = new Properties(); properties.load(new FileInputStream(filename)); return properties; }
  • 9. KISS - Example 1 (Overthinking) Let’s handle some exceptions! public Properties readAllLinesFromFileAndReturnPropertiesObject(File file) { Properties properties = null; if (file != null) { ... } else { throw new IllegalArgumentException("file which should contains all needed information " + "to init Properties object is null, that means that Java can't work with it, " + "please check your code and make sure that you are passing valid arguments", new NullPointerException() ); } return properties; }
  • 10. KISS - Example 1 (Overthinking) And several more... public Properties readAllLinesFromFileAndReturnPropertiesObject(File file) { Properties properties = null; if (file != null) { if (file.exists()) { if (file.canRead()) { try { BufferedReader bufferedReaderForFileWhichShouldContainsLines = new BufferedReader( new InputStreamReader( new BufferedInputStream( new FileInputStream(file) ) ) ); try { String accumulatorForLineFromFile = null; properties = new Properties(); while ((accumulatorForLineFromFile = bufferedReaderForFileWhichShouldContainsLines.readLine()) != null) { properties.setProperty( accumulatorForLineFromFile.split("=")[0], accumulatorForLineFromFile.split("=")[1] ); } } catch (IOException ioException) { throw new IllegalArgumentException("file which should contains all needed information " + "to init Properties object is not null, but it isn't suitable for reading, " + "that means that Java can't work with it, " + "please check your code and make sure that you are passing valid arguments", new IOException(ioException) ); } finally { try { bufferedReaderForFileWhichShouldContainsLines.close(); } catch (IOException ioException) { System.err.printf("Can't close bufferedReaderForFileWhichShouldContainsLines: %s", ioException.getMessage() ); } } } catch (FileNotFoundException fileNotFoundException) { throw new IllegalArgumentException("file which should contains all needed information " + "to init Properties object is not null, but it not found, " + "that means that Java can't work with it, " + "please check your code and make sure that you are passing valid arguments", new FileNotFoundException(fileNotFoundException.getMessage()) ); } } else { throw new IllegalArgumentException("file which should contains all needed information " + "to init Properties object is not null, but it now unreadable, " + "that means that Java can't work with it, " + "please check your code and make sure that you are passing valid arguments", new IllegalAccessException() ); } } else { throw new IllegalArgumentException("file which should contains all needed information " + "to init Properties object is not null, but it isn't exists, " + "that means that Java can't work with it, " + "please check your code and make sure that you are passing valid arguments", new IllegalAccessException() ); } } else { throw new IllegalArgumentException("file which should contains all needed information " + "to init Properties object is null, that means that Java can't work with it, " + "please check your code and make sure that you are passing valid arguments", new NullPointerException() ); } return properties; }
  • 11. KISS - Example 1 (Laziness) Let’s handle some exceptions! public Properties readProperties(String filename) throws IOException { Properties properties = new Properties(); properties.load(new FileInputStream(filename)); return properties; }
  • 12. Naming best & bad practices Programming routine:
  • 13. Naming best & bad practices Programming routine:
  • 14. Naming best practices ● Keep all names close to context and self-describing ○ But avoid “secret knowledge” ○ Share the context via javadoc or comments
  • 15. Naming best practices ● Keep all names close to context and self-describing ○ But avoid “secret knowledge” ○ Share the context via javadoc or comments ● Variable type should be obvious ○ That doesn’t mean that name should contain Type
  • 16. Naming best practices ● Keep all names close to context and self-describing ○ But avoid “secret knowledge” ○ Share the context via javadoc or comments ● Variable type should be obvious ○ That doesn’t mean that name should contain Type ● Boolean variables/methods names should be suitable for the sentence: “if <variable_name> then ...?”
  • 17. Naming best practices ● Keep all names close to context and self-describing ○ But avoid “secret knowledge” ○ Share the context via javadoc or comments ● Variable type should be obvious ○ That doesn’t mean that name should contain Type ● Boolean variables/methods names should be suitable for the sentence: “if <variable_name> then ...?” ● Methods names should answer the question “what to do?”
  • 18. Naming best practices ● Keep all names close to context and self-describing ○ But avoid “secret knowledge” ○ Share the context via javadoc or comments ● Variable type should be obvious ○ That doesn’t mean that name should contain Type ● Boolean variables/methods names should be suitable for the sentence: “if <variable_name> then ...?” ● Methods names should answer the question “what to do?” ● Type names might contain parent names
  • 20. Naming bad practices ● Using words that means nothing: obj, data, value, tmp... a. There is always place for exceptions
  • 21. Naming bad practices ● Using words that means nothing: obj, data, value, tmp... a. There is always place for exceptions ● Fake/Wrong variable type a. This might cost a burned chair...
  • 22. Naming bad practices ● Using words that means nothing: obj, data, value, tmp... a. There is always place for exceptions ● Fake/Wrong variable type a. This might cost a burned chair... ● Single-character names: w, t, f ... o, m, g a. Especially without any context - 100% burned chair
  • 23. Naming bad practices ● Using words that means nothing: obj, data, value, tmp... a. There is always place for exceptions ● Fake/Wrong variable type a. This might cost a burned chair... ● Single-character names: w, t, f ... o, m, g a. Especially without any context - 100% burned chair ● Fake/Incomplete names of the methods
  • 24. Naming bad practices ● Using words that means nothing: obj, data, value, tmp... a. There is always place for exceptions ● Fake/Wrong variable type a. This might cost a burned chair... ● Single-character names: w, t, f ... o, m, g a. Especially without any context - 100% burned chair ● Fake/Incomplete names of the methods ● Public argument names based on secret knowledge a. Especially without any context - 200% burned chair
  • 25. Dirty and Pure methods Hello, my name is side-effect... public int[] sortArray(int[] array) { Arrays.sort(array); return array; }
  • 26. Dirty and Pure methods And sometimes I’m not obvious at all… public <T> T[] sortArray(T[] array) { if (array == null || array.length < 2) return array; Comparator<T> comparator = null; T[] tmpArray = checkAndReturnArray(array); T notNullElement = null; for (int i = 0; i < tmpArray.length && notNullElement == null; notNullElement = tmpArray[i++]) ; if (notNullElement == null) return array; if (notNullElement instanceof Comparator) { comparator = (Comparator<T>) notNullElement; } else if (notNullElement instanceof Comparable) { comparator = (o1, o2) -> { if (o1 == null) return 1; if (o2 == null) return -1; return ((Comparable<T>) o1).compareTo(o2); }; } if (comparator == null) return array; Arrays.sort(tmpArray, comparator); return tmpArray; }
  • 27. Dirty and Pure methods Here's Johnny! /** * Checks array and returns copy if Mars is in the zenith of Saturn */ public <T> T[] checkAndReturnArray(T[] array) { return (array != null) ? ((System.currentTimeMillis() > (42 * 64 * 30 * 365)) ? ((System.getenv("magic") == null) ? array : null) : array) : null; }
  • 28. Dirty and Pure methods Here's Johnny! /** * Checks array and returns copy if Mars is in the zenith of Saturn */ public <T> T[] checkAndReturnArray(T[] array) { return (array != null) ? ((System.currentTimeMillis() > (42 * 64 * 30 * 365)) ? ((System.getenv("magic") == null) ? array : null) : array) : null; }
  • 29. Immutability and final keyword If you can’t change the methods, you can change the arguments...
  • 30. Immutability and final keyword What is immutability? class Immutable { private final String immutableField; public Immutable(String immutableField) { this.immutableField = immutableField; } public String getImmutableField() { return immutableField; } } Examples: String, Integer, File, URL...
  • 31. Immutability and final keyword What is immutability? class Immutable { private final String immutableField; public Immutable(String immutableField) { this.immutableField = immutableField; } public String getImmutableField() { return immutableField; } } Examples: String, Integer, File, URL... What is mutability? class Mutable { private List<String> mutableField; public List<String> getMutableField() { return mutableField; } public void setMutableField(List<String> mutableField) { this.mutableField = mutableField; } } Examples: ArrayList, Arrays, StringBuilder...
  • 32. Immutability and final keyword Why immutability is good? ● Preventing side-effects ● Thread-safe ● Easy to debug ● Easy to implement ● Easy to extend ● Easy to scale
  • 33. Immutability and final keyword Why immutability is good? ● Preventing side-effects ● Thread-safe ● Easy to debug ● Easy to implement ● Easy to extend ● Easy to scale Why immutability is bad? ● Real world isn’t immutable ● Constraints you ● Not always convenient ● Increases memory usage ● Performance degradation ● There is always will be an exception...
  • 34. Immutability and final keyword Keyword final can be used with: ● Variables ○ final Object someField;
  • 35. Immutability and final keyword Keyword final can be used with: ● Variables ○ final Object someField; ● Methods ○ final public void someMethod() { ... } ○ public void someMethod(final Object argument) { ... }
  • 36. Immutability and final keyword Keyword final can be used with: ● Variables ○ final Object someField; ● Methods ○ final public void someMethod() { ... } ○ public void someMethod(final Object argument) { ... } ● Classes ○ public final class Example3;
  • 37. try-catch-finally pitfalls Simple puzzle? public static int puzzle() { try { return 5; } catch (Exception ex) { return 10; } finally { return 15; } }
  • 38. try-catch-finally pitfalls Simple puzzle? public static int puzzle() { try { return 5; } catch (Exception ex) { return 10; } finally { return 15; } }
  • 39. try-catch-finally pitfalls try pitfalls ● It’s a new scope… ● Each line might raise exception ● catch or finally is required ● Try with resources? ○ Custom AutoCloseable implementation ○ Implicit side-effect
  • 40. try-catch-finally pitfalls catch pitfalls ● It’s a new scope… ● Type erasing ● Performance degradation ● Exception-oriented logic
  • 41. try-catch-finally pitfalls finally pitfalls ● It’s a new scope… ● WILL BE EXECUTED ALWAYS!!! ○ Except for that moment, in which you will really need this... ● Might cause performance degradation ● Newer return value in finally ○ But sometimes...
  • 42. Early exception handling Exception handling public int someMethod(String arg1, String arg2) { final int defaultValue = 42; int value = 0; try { int int1 = Integer.parseInt(arg1); int int2 = Integer.parseInt(arg2); value = int1 / int2; } catch (Exception ex) { System.err.println(ex); return defaultValue; } return value; }
  • 43. Early exception handling Exception handling public int someMethod(String arg1, String arg2) { final int defaultValue = 42; int value = 0; try { int int1 = Integer.parseInt(arg1); int int2 = Integer.parseInt(arg2); value = int1 / int2; } catch (Exception ex) { System.err.println(ex); return defaultValue; } return value; } Early exception handling public int someMethod(String arg1, String arg2) { final int defaultValue = 42; if (notNumber(arg1) || notNumber(arg2)) { return defaultValue; } int int1 = Integer.parseInt(arg1); int int2 = Integer.parseInt(arg2); if (int2 == 0) { return defaultValue; } int value = int1 / int2; return value; }
  • 44. Early exception handling ● Objects.requireNonNull(argument); (throw early)
  • 45. Early exception handling ● Objects.requireNonNull(argument); (throw early) ● Use IllegalArgumentException() (throw early)
  • 46. Early exception handling ● Objects.requireNonNull(argument); (throw early) ● Use IllegalArgumentException() (throw early) ● Use UnsupportedOperationException() (throw early)
  • 47. Early exception handling ● Objects.requireNonNull(argument); (throw early) ● Use IllegalArgumentException() (throw early) ● Use UnsupportedOperationException() (throw early) ● Delegate exception handling, use throws (catch late)
  • 48. Early exception handling ● Objects.requireNonNull(argument); (throw early) ● Use IllegalArgumentException() (throw early) ● Use UnsupportedOperationException() (throw early) ● Delegate exception handling, use throws (catch late) ● Write javadoc ● Write logs
  • 49. Why null is bad? ● More than 2500 NPE defects in our Jira
  • 50. Why null is bad? ● More than 2500 NPE defects in our Jira ● null is low-level concept
  • 51. Why null is bad? ● More than 2500 NPE defects in our Jira ● null is low-level concept ● Zero information
  • 52. Why null is bad? ● More than 2500 NPE defects in our Jira ● null is low-level concept ● Zero information ● null instanceof Type --> false
  • 53. Why null is bad? ● More than 2500 NPE defects in our Jira ● null is low-level concept ● Zero information ● null instanceof Type --> false ● int value = (Integer) null; --> NPE
  • 54. Why null is bad? ● More than 2500 NPE defects in our Jira ● null is low-level concept ● Zero information ● null instanceof Type --> false ● int value = (Integer) null; --> NPE ● Many methods uses .toString() --> NPE ○ String.valueOf(obj) - solves this issue
  • 55. Why null is bad? ● More than 2500 NPE defects in our Jira ● null is low-level concept ● Zero information ● null instanceof Type --> false ● int value = (Integer) null; --> NPE ● Many methods uses .toString() --> NPE ○ String.valueOf(obj) - solves this issue ● Null-oriented programming is legacy ○ Use Optional<T> instead
  • 56. Lean refactoring ● Don’t broke tests (Red-Green-Refactor)
  • 57. Lean refactoring ● Don’t broke tests (Red-Green-Refactor) ● Don’t change signatures
  • 58. Lean refactoring ● Don’t broke tests (Red-Green-Refactor) ● Don’t change signatures ● Don’t change parameters order ○ Especially for constructors
  • 59. Lean refactoring ● Don’t broke tests (Red-Green-Refactor) ● Don’t change signatures ● Don’t change parameters order ○ Especially for constructors ● Don’t change contract
  • 60. Lean refactoring ● Don’t broke tests (Red-Green-Refactor) ● Don’t change signatures ● Don’t change parameters order ○ Especially for constructors ● Don’t change contract ● Use @Deprecated
  • 61. Abusing Java Just because you can, it doesn’t mean you should... ● Use enum as Singleton
  • 62. Abusing Java Just because you can, it doesn’t mean you should... ● Use enum as Singleton ● Use static as Singleton
  • 63. Abusing Java Just because you can, it doesn’t mean you should... ● Use enum as Singleton ● Use static as Singleton ● Use reflection ○ Especially for internal JDK classes
  • 64. Abusing Java Just because you can, it doesn’t mean you should... ● Use enum as Singleton ● Use static as Singleton ● Use reflection ○ Especially for internal JDK classes ● Use interface just because of signature
  • 65. Abusing Java Just because you can, it doesn’t mean you should... ● Use enum as Singleton ● Use static as Singleton ● Use reflection ○ Especially for internal JDK classes ● Use interface just because of signature ● Use inheritance as aggregation/delegation
  • 66. Abusing Java Just because you can, it doesn’t mean you should... ● Use enum as Singleton ● Use static as Singleton ● Use reflection ○ Especially for internal JDK classes ● Use interface just because of signature ● Use inheritance as aggregation/delegation ● ... ● If it works, it doesn’t mean it’s good.
  • 67. SOLID in the nutshell ● S - Single responsibility
  • 68. SOLID in the nutshell ● S - Single responsibility ● O - Opened for extension, but closed for changes
  • 69. SOLID in the nutshell ● S - Single responsibility ● O - Opened for extension, but closed for changes ● L - Liskov substitution, children should keep parents contracts.
  • 70. SOLID in the nutshell ● S - Single responsibility ● O - Opened for extension, but closed for changes ● L - Liskov substitution, children should keep parents contracts. ● I - Interface segregation is better than God-interface.
  • 71. SOLID in the nutshell ● S - Single responsibility ● O - Opened for extension, but closed for changes ● L - Liskov substitution, children should keep parents contracts. ● I - Interface segregation is better than God-interface. ● D - Dependency inversion, build dependencies over abstractions, not over implementations.
  • 72. Q&A Session (the end) Attention! Thanks for your attention!