Best Practices for Coding Java
While Josh Bloch Effective Java rule remains pretty effective when it comes to everyday tasks there are some more subtle practices to be applied in less common situations involving API / SPI design.
1. Remember C++ Destructors
Remember C++ destructors? Have you ever had to debug through any code leaving memory leaks because allocated memory was not freed after extracting an object? Still destructors have a peculiar feature. In many cases you had better free memory in the inverse order of allocation. Keep this rule in mind when you're using @Before and @After JUnit annotations or when allocating, freeing JDBC resources.
2. Don't Trust Your Early SPI Evolution Judgment
When providing an SPI to your consumers keep in mind that your SPI evolution judgment may mislead you. You might think you will need this extra parameter. Just refrain from adding any functionality early. As soon as you've published your SPI and decided following semantic versioning, you can realize that you might need another argument instead of previously added method to your SPI. So the best solution is to communicate results through a MessageResult type constructed through a builder API. This will even increase SPI evolution flexibility.
3. Don't Return Anonymous, Local, or Inner Classes
Refrain from using anonymous, local, or inner classes frequently because they keep a reference to the outer instance. This can lead to memory leaks, as your whole object graph will suddenly entangle in subtle ways. Follow the rule: when writing an anonymous, local or inner class, verify whether you can make it static or even a regular top-level class. Try not to return anonymous, local or inner class instances from methods to the outside scope.
4. Start Writing SAMs!
Java 8 is bringing with it lambdas, which your API consumers may like. So you had better ensure that they can use them often as well. If your API accepts simple "scalar" types such as int, long, String, Date, why not accept SAMs too. A SAM is a Single Abstract Method also known as a functional interface. This confirms rule number 2, where EventListener is in fact a SAM. The best SAMs feature single arguments to be further simplified in writing a lambda.
5. Don't Return Null from API Methods
While NULLs and NullPointerExceptions can't be completely avoided, consider designing your API in such a way that users will face fewer problems. Whenever possible strive to avoid returning null from API methods.
6. Don't Return Null Arrays or Lists from API Methods
Even thought there are some situations when returning nulls from methods makes sense, there is not true when it comes to returning null arrays or null collections! In fact, null neither helps find the error nor distinguish I/O errors from the File instance not being a directory. The notion of "absence" should be implemented by empty arrays or collections. The rule says that arrays or collections should never be null.
7. Avoid State, Be Functional
As HTTP is stateless relevant state is transferred in each request and in each response. This is a key aspect of REST: Representational State Transfer. It is much easier to work if state is transferred in various objects, instead of being manipulated from the outside. In fact, there are two main issues to consider. First, it is difficult to deal with stateful APIs in multi-threaded environments. Second, it is practically impossible to make stateful resources available around the world, as the state is not documented. Consequently try to follow the rule: implement more of a functional style and pass state through method arguments. Try to manipulate less object state.
8. Short-Circuit Equals()
Make sure you short-circuit all your equals() methods to enhance performance.
9. Make Methods Final by Default
In case you control all source code, making methods final by default is OK. The reason is that if you need to override a method, you can easily remove the final keyword. Plus you won't be able to accidentally override any method anymore. This strategy works for static methods in particular, where "overriding" is useless. So the rule is: if you're in full control of your API, make sure you make methods final by default.
10. Avoid the Method(T…) Signature
Skip "accept-all" signatures whenever possible. If you cannot do it, don't overload this method ever. This means that, every time you have an "accept-all" signature (even a generic one), you will fail to type safely overload it. If you are beginner in Java programming and would like to start a career in this field consider entering a four-year college to get a bachelor's degree in computer science or programming. To decrease your tuition costs check out best computer programming scholarships available to students. Also to be versed in the latest trends in the industry you are required to read top Java programming books and attend conferences for developers. All these will help you become a specialist in the field and make a brilliant career in computer programming world.