📜 Best Practices

The idea behind Effective Java is to utilize and/or adapt the usage of varies tools in the Java developers toolkit. It has been separated into 11 topics, which range from object creation to serialization. Each topic has a number of recommendations, where Joshua Bloch goes into the how and why, you should use these coding recommendations.

Based on previous experiences, I find that my learning process improves from using the Feynman technique. I therefore thought that I would write my own abridged versions of Joshua’s recommendations. My hope being that they would stick better to my own memory and so that they perhaps could be shared with other developer, which had not read or known the book.

INTEGU-java-best-practices-85-Avoid-serialization

Serialization

Avoid Java serialization if possible

Serialization was intended as a utility within the Java language, which allows objects to be converted into bytes (serialized), send to another endpoint, and reconstructed as an object again (deserialized). This is necessary since java objects only exists within the JVM and can therefore not be send directly.

INTEGU-java-best-practices-84-thread-schedulers

Concurrency

78. Use Synchronize When Handling Mutable Methods
When working with threads, synchronize on mutable methods becomes a valuable resource. This is because of two reasons:

Synchronize ensure the method can only be accessed by one thread at a time. Any thread attempting to execute the method while it is already in use, will be put on hold until the method is available again.
Because the threads are set to wait for each other, synchronize also guarantee that each thread will be able to see changes to the mutable method made by previous threads.
A mutable method could for example be a method providing an incremental serial number based on a field instance.

INTEGU-java-best-practices-49-argument-validity-50-defensive-copies

Methods

Assert method arguments validity
Whenever an object is given in as a method argument, it should be asserted in terms of validity as the first thing.

This can be done with something as Objects.requireNonNull(arg), which will throw an exception if the argument is null.

Additionally, if you want to determine which arguments, should be allowed to be nullable, the @Nullable annotation can be used.

INTEGU-java-best-practices-27-Generics-unchecked-warnings

Generics

26. Don’t Use Raw Types
Since Java 5, generics were introduced. However, before that Collections (e.g. List) where still part of the language.

With generics it became possible to declare, inside the diamond declaration (), which type a List would be working with. Without a diamond declaration, it would be classified as a raw type.

Because of backwards compatibility these raw types where not removed after java 5’s release. However, regardless of them being part of the language, they should never be used.

Raw types enable the possibility to add unintended objects to the List, which will throw an exception at runtime.

INTEGU-java-best-practices-15-Limit-access-to-class-members

Classes & Interfaces

15. Limit Accessibility To Classes And Members
Generally, any class or member of a class should have the lowest possible access level, which still allows for its functionality to work.

API Example:

Take the case of an externally exposed API, where the interface represents all public accessible methods. Any implementation of this interface should only have public access level on the implemented methods.

The additional members of the implementing class should never be made public. Ideally private or package-private if required for unit testing.

In the case of the exposed API, any publicly available member of the implementation will have to be supported forever, if they have once been published. If members are degraded to a lower access level, it will ruin the API’s backwards compatibility.

INTEGU-java-best-practices-10-guidelines-of-equals

Methods Common to All Objects

Follow The Guidelines Of The Equals-Method
The equals-method need to obey the following four rules to remain functional.

Reflexive: x.equals(x) = true

Symmertric: x.equals(y) = y.equals(x)

Transitive: x.equals(y) = y.equals(z) = true -> z.equals(x) = true

Consistent: x.equals(y) remains the same as long as x and y does not change.

How to write a good equals method:

(Regardless of most IDEs autogenerating them)

First use == to check if the object is equivilent to “this”.
Use instanceof to check if the object is the correct class instance. Otherwise return false.
Cast the object to the same instance as “this”
Check with == if all relevant fields of the class match each other.

Scroll to Top
INTEGU - Cookie-consent

INTEGU uses cookies to personalize your experience and provide traceability for affiliate links. By using the website, you agree to these terms and conditions. To learn more see the privacy policy page.