33 |
34 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/pages.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "section": "Basics",
4 | "links": [
5 | { "name": "Syntax", "link": "#basics/syntax" },
6 | { "name": "Exceptions", "link": "#basics/exceptions" },
7 | { "name": "120c", "link": "#basics/120c" },
8 | { "name": "Whitespaces", "link": "#basics/whitespaces" },
9 | { "name": "Classes", "link": "#basics/classes" },
10 | { "name": "Methods", "link": "#basics/methods" },
11 | { "name": "Generics", "link": "#basics/generics" },
12 | { "name": "Other language basics", "link": "#basics/other-language-basics" }
13 | ]
14 | }, {
15 | "section": "Java EE",
16 | "links": [
17 | { "name": "JPA", "link": "#jee/jpa" },
18 | {
19 | "section": "EJB",
20 | "links": [
21 | { "name": "Stateless", "link": "#jee/ejb/stateless" },
22 | { "name": "Stateful", "link": "#jee/ejb/stateful" },
23 | { "name": "MessageDriven", "link": "#jee/ejb/mdb" },
24 | { "name": "CDI", "link": "#jee/ejb/cdi" }
25 | ]
26 | }
27 | ]
28 | }, {
29 | "section": "Patterns",
30 | "links": [
31 | { "name": "Design Patterns (GOF)", "link": "#patterns/gof" },
32 | { "name": "JEE Patterns", "link": "#patterns/jee" }
33 | ]
34 | }
35 | ]
36 |
--------------------------------------------------------------------------------
/pages/basics/120c.md:
--------------------------------------------------------------------------------
1 | # 120c vs 80c vs _infinite_c
2 |
3 | While most languages prefer to respect the "old" 80c rule, in Java, usually,
4 | we respect the 120c rule.
5 |
6 | This happens due to the language verbosity. 80c in Java is really nothing.
7 | 120c is enough.
8 |
9 | I will not enter in details about that. You could just Google about the 80c/120c
10 | rules.
11 |
--------------------------------------------------------------------------------
/pages/basics/classes.md:
--------------------------------------------------------------------------------
1 | ## Classes
2 |
3 | Classes are the building blocks of any Java application and if these building blocks are not written carefully, it could lead to design issues in production or maintenance.
4 |
5 | ## 5 recommended design principles
6 |
7 | The 5 design principles can be referred to as `SOLID` in short.
8 |
9 | They are:
10 |
11 | ```
12 | 1. Single Responsibility Principle
13 | 2. Open Closed Principle
14 | 3. Liskov’s Substitution Principle
15 | 4. Interface Segregation Principle
16 | 5. Dependency Inversion Principle
17 | ```
18 |
19 | Let's discuss them one by one:
20 |
21 | ```
22 | 1. Single Responsibility Principle: One class, one responsibility
23 | ```
24 |
25 | A class should be written for only one purpose. All its services should be narrowly aligned with that responsibility. If it is model class, then it should represent only one entity. This will give you the flexibility to make changes in future without worrying about the impact of changes on other entities.
26 |
27 | For example, consider a module that compiles and prints a report. Such a module can be changed for two reasons. First, the content of the report can change. Second, the format of the report can change. These two things change for very different causes; one substantive, and one cosmetic. The single responsibility principle says that these two aspects of the problem are really two separate responsibilities, and should therefore be in separate classes or modules. It would be a bad design to couple two things that change for different reasons at different times.
28 |
29 | ```
30 | 2. Open Closed Principle: Software components should be open for extension, but closed for modification
31 | ```
32 |
33 | Classes should be designed in such a way that whenever fellow developers wants to change the flow of control in specific conditions in application, all they need to extend your class and override some functions. Design of a class should be in such a way that it allows its behaviour to be extended without modifying its source code.
34 |
35 | For example, if you take a look into any good framework like struts or spring, you will notice that you can't change their core logic and request processing, but you can modify the desired application flow just by extending some classes and putting them in configuration files.
36 |
37 | ```
38 | 3. Liskov’s Substitution Principle: Objects should be replaceable with instances of their subtypes
39 | ```
40 |
41 | Classes created by extending your class should be able to fit in the application without altering the correctness of the program. It can be achieved by strictly adhering to the single responsibility principle.
42 |
43 | For example, if S is a subtype of T, then objects of type T may be replaced with objects of type S without causing any fatal exceptions.
44 |
45 | ```
46 | 4. Interface Segregation Principle: Many specific interfaces are better than one general interface
47 | ```
48 |
49 | Interface Segregation Principle is applicable to interfaces as single responsibility principle holds to classes. Clients should not be forced to implement unnecessary methods which they will not use.
50 |
51 | For example, a developer created an interface and added two methods. Now a client wants to use this interface, but he intends to use only one method. In such cases, two interfaces should be created by breaking the existing one.
52 |
53 | ```
54 | 5. Dependency Inversion Principle: Depend on abstractions, not on concretions
55 | ```
56 |
57 | It is a specific form of decoupling software modules, where all modules expose only abstraction which is useful in extending the functionality in another module. You should design your software in such a way that various modules can be separated from each other using an abstract layer to bind them together.
58 |
59 | For example, in spring framework, all modules are provided as separate components which can work together by simply injected dependencies in other module. They are so well closed in their boundaries that you can use them in other software modules apart from spring with same ease.
--------------------------------------------------------------------------------
/pages/basics/exceptions.md:
--------------------------------------------------------------------------------
1 | # Exception Handling
2 |
3 | ## Don't log and throw
4 |
5 | Please, just don't do that. You will log the exception, probably another catch
6 | will do the same. You will end up having 2Mb of logs about the same exception.
7 |
8 | Bad:
9 |
10 | ```java
11 | catch (Exception ex) {
12 | logger.warn("I got an exception!", ex);
13 | throw ex;
14 | }
15 | ```
16 |
17 | Better:
18 |
19 | ```java
20 | catch (Exception ex) {
21 | logger.warn("I got an exception!", ex);
22 | }
23 | ```
24 |
25 | ## Don't log just the message
26 |
27 | The stack is probably important.
28 |
29 | Bad:
30 |
31 | ```java
32 | catch (Exception ex) {
33 | logger.warn("I got an exception: " + ex.getMessage());
34 | }
35 | ```
36 |
37 | Better:
38 |
39 | ```java
40 | catch (Exception ex) {
41 | logger.warn("I got an exception!", ex);
42 | }
43 | ```
44 |
45 | ## Don't catch and throw
46 |
47 | Bad:
48 |
49 | ```java
50 | catch (Exception e) {
51 | e.printStackTrace();
52 | throw new Exception(e);
53 | }
54 | ```
55 |
56 | ## Use try-with-resources for closeable objects (prior to Java 7)
57 |
58 | Good:
59 |
60 | ```java
61 | BufferedReader br = new BufferedReader(new FileReader(path));
62 | try {
63 | return br.readLine();
64 | } finally {
65 | if (br != null) br.close();
66 | }
67 | ```
68 |
69 | Better:
70 |
71 | ```java
72 | try (BufferedReader br = new BufferedReader(new FileReader(path))) {
73 | return br.readLine();
74 | }
75 | ```
76 |
77 | ## Always do something with the exception
78 |
79 | If you can somehow recover from an exception, **do it**.
80 |
81 | The golden rule is: **never catch an exception that you can't recover from**.
82 |
--------------------------------------------------------------------------------
/pages/basics/generics.md:
--------------------------------------------------------------------------------
1 | # Generics
2 |
3 | The general rule for this is: **never cast**. 99.99999999% of the time you
4 | cast something, there is another way to do it.
5 |
6 | Also, avoid with will the `@SupressWarnings` annotation.
7 |
--------------------------------------------------------------------------------
/pages/basics/methods.md:
--------------------------------------------------------------------------------
1 | # Method declarations
2 |
3 | ## Single Responsibility
4 |
5 | Methods should do one thing. Only one. For example, if your method is called
6 | `save`, it should **save** something. This is what everyone what will read the code
7 | will expect to.
8 |
9 | Method name should say what it do. When other developers read your code, they
10 | should be able to understand what any given method call will do, without read
11 | the method source code.
12 |
13 | Be succinct: Don't use a lot of words in your method name. For example:
14 | `saveDocumentAndBuildSomethingAndReturnThatThing`. Also, if you have or feel like
15 | you should put a `and` noun in your method name, maybe it's time to split your method into a more single-responsibility way.
16 |
17 | ## Javadoc
18 |
19 | Please, doesn't matter how much stupid the method might look like, fill
20 | the javadoc the best you can.
21 |
22 | ## Deprecating things
23 |
24 | Bad:
25 |
26 | ```java
27 | public void doSomething()
28 | throw Exception("This method is deprecated");
29 | }
30 |
31 | /**
32 | * please don't use this method anymore.
33 | **/
34 | public void doSomething2()
35 | }
36 | ```
37 |
38 | Better:
39 |
40 | ```java
41 | /**
42 | *
43 | * @Deprecated: due to "some reason", this method is now
44 | * deprecated, please use {@link #thisMethod()} instead.
45 | *
46 | **/
47 | public void doSomething()
48 | // leave the old code if possible, or adapt it to call the
49 | // new method.
50 | }
51 | ```
52 |
--------------------------------------------------------------------------------
/pages/basics/other-language-basics.md:
--------------------------------------------------------------------------------
1 | # Other Language Basics
2 |
3 | ## Naming things
4 |
5 | - Try not to name things like `acf`, `dsg`, `sirfs` and things like that;
6 | - An object which will be used to log things is a `logger`, because it `logs`
7 | this. `log` is what the `logger` writes;
8 | - Constants should be `WRITTEN_LIKE_THIS`;
9 | - It is obvious that a property named `color` inside a `car` object is the
10 | `color` of the `car`. You don't need to name the property `carColor`. Avoid
11 | unneeded verbosity;
12 | - Use names that show your purpose, if you need comments to explain about
13 | a variable, then the name does not show your purpose.
14 | Example: `int dayPeriod = 5;` rather than `int day = 5; // day period`
15 |
16 | ## `this` is for disambiguation only
17 |
18 | That's it. Don't use `this` keyword with the purpose to make it more readable,
19 | you are doing the opposite.
20 |
21 | ## Booleans
22 |
23 | You don't need to do conditionals to, for example, return `true` or `false`.
24 | The expression itself is a boolean already:
25 |
26 | Bad:
27 |
28 | ```java
29 | private boolean hasContent(String field) {
30 | return (field != null && !field.trim().isEmpty()) ? true : false;
31 | }
32 | ```
33 |
34 | Better:
35 |
36 | ```java
37 | private boolean hasContent(String field) {
38 | return field != null && !field.trim().isEmpty();
39 | }
40 | ```
41 |
42 | ## String Concatenations
43 |
44 | You should avoid the use of the `+` operator while dealing with Strings.
45 | Yes, the JVM itself will turn it into a `StringBuilder`, but, it could not
46 | be in the best way. In general, use `StringBuilder` will be more readable
47 | and will save you some runtime. You can see some examples regarding this
48 | [here][concat-tests].
49 |
50 | As you may have seen in the [previous link][concat-tests], concatenating
51 | Strings inside a loop will lead to a not-so-good-implementation. For
52 | example, the following code:
53 |
54 | ```java
55 | String out = "";
56 | for( int i = 0; i < 10000 ; i++ ) {
57 | out = out + i;
58 | }
59 | return out;
60 | ```
61 |
62 | will be "translated" to something like:
63 |
64 | ```java
65 | String out = "";
66 | for( int i = 0; i < 10000; i++ ) {
67 | out = new StringBuilder().append(out).append(i).toString();
68 | }
69 | return out;
70 | ```
71 |
72 | which is not the best implementation, since it creates "useless" `StringBuilder`
73 | instances (one per iteration). The best implementation will probably be:
74 |
75 | ```java
76 | StringBuilder out = new StringBuilder();
77 | for( int i = 0 ; i < 10000; i++ ) {
78 | out.append(i);
79 | }
80 | return out.toString();
81 | ```
82 |
83 | One more example:
84 |
85 | Bad:
86 |
87 | ```java
88 | if (result != null && (!result.isEmpty())) {
89 | String message = I18nService.translate("some message.\n");
90 | message += I18nService.translate("another message.\n");
91 | for (int c = 0; c < result.size(); c++) {
92 | SomeObj obj = result.get(c);
93 | message += obj.getPK().getId();
94 | message += " - ";
95 | message += obj.getPK().getVersion();
96 | message += " - ";
97 | message += obj.getDescription();
98 | message += "\n";
99 | }
100 | logger.error(message);
101 | }
102 | ```
103 |
104 | Better:
105 |
106 | ```java
107 | if (result != null && !result.isEmpty()) {
108 | StringBuilder message = new StringBuilder();
109 | message.append(I18nService.translate("some message.\n"));
110 | message.append(I18nService.translate("another message.\n"));
111 | for (SomeObj obj : result) {
112 | SomeObjPK pk = obj.getPK();
113 | message.append(pk.getId()).append(" - ");
114 | message.append(pk.getVersion()).append(" - ");
115 | message.append(obj.getDescription()).append("\n");
116 | }
117 | logger.error(message.toString());
118 | }
119 | ```
120 |
121 | And just don't do this kind of nonsense things:
122 |
123 | ```java
124 | new StringBuilder("str").append(var2 + " ");
125 | ```
126 |
127 | > **PROTIP**: There is also this thing called `String Pool`. You may want to
128 | read about it.
129 |
130 | [concat-tests]: https://github.com/caarlos0/string-concat-tests
131 |
--------------------------------------------------------------------------------
/pages/basics/syntax.md:
--------------------------------------------------------------------------------
1 | # Syntax
2 |
3 | Some good practices related to syntax.
4 |
5 | ## Brackets
6 |
7 | In general, it's good to always use brackets.
8 |
9 | Bad:
10 |
11 | ```java
12 | if (someVar != null)
13 | someVar = new SomeClass();
14 | anotherVar = new AnotherClass(someVar);
15 |
16 | if (someVar != null)
17 | {
18 | someVar = new SomeClass();
19 | anotherVar = new AnotherClass(someVar);
20 | }
21 |
22 | if (someVar != null){
23 | someVar = new SomeClass();
24 | anotherVar = new AnotherClass(someVar);
25 | }
26 | ```
27 |
28 | Better:
29 |
30 | ```java
31 | if (someVar != null) {
32 | someVar = new SomeClass();
33 | }
34 |
35 | if (someVar != null)
36 | someVar = new SomeClass();
37 | ```
38 |
39 | ## Loops and Conditionals
40 |
41 | Always leave a space between the command and the first parenthesis, as well
42 | between the last parenthesis and the brackets.
43 |
44 | Bad:
45 |
46 | ```java
47 | if(someVar != null){
48 | someVar = new SomeClass();
49 | }
50 |
51 | if(someVar != null)
52 | {
53 | someVar = new SomeClass();
54 | }
55 | ```
56 |
57 | Better:
58 |
59 | ```java
60 | if (someVar != null) {
61 | someVar = new SomeClass();
62 | }
63 | ```
64 |
65 | Also, in for-each statements, always put spaces around the `:`.
66 |
67 | Bad:
68 |
69 | ```java
70 | for(SomeClass someVar:someVars){
71 | someVar.doSomething();
72 | }
73 |
74 | for(SomeClass someVar:someVars)
75 | {
76 | someVar.doSomething();
77 | }
78 | ```
79 |
80 | Better:
81 |
82 | ```java
83 | for (SomeClass someVar : someVars) {
84 | someVar.doSomething();
85 | }
86 |
87 | for (SomeClass someVar : someVars)
88 | someVar.doSomething();
89 | ```
90 |
91 |
--------------------------------------------------------------------------------
/pages/basics/whitespaces.md:
--------------------------------------------------------------------------------
1 | # Spaces
2 |
3 | ## Trailing withespaces
4 |
5 | Whatever editor you use, configure it to automatically remove trailing whitespaces.
6 | No one deserves a messed diff because of it.
7 |
8 | If you use git, you can also add a commit hook to do this.
9 |
10 | ## TAB vs SPACEs and TAB size
11 |
12 | Is a convention in Java-world to ident with **4 spaces sized hard tabs**, even
13 | if a lot of other laguages uses, in general, 2 spaces soft tabs, and even if
14 | Oracle actually recommends 8 spaces hard tabs (which is insane).
15 |
--------------------------------------------------------------------------------
/pages/home.html:
--------------------------------------------------------------------------------
1 |
2 |
Java Best Practices
3 |
4 | A practical guide through all sort of nonsense things people should not
5 | do while coding Java.
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/pages/jee/ejb/cdi.md:
--------------------------------------------------------------------------------
1 | # CDI
2 |
3 | > TODO
4 |
--------------------------------------------------------------------------------
/pages/jee/ejb/mdb.md:
--------------------------------------------------------------------------------
1 | # Message Driven Bean
2 |
3 | > TODO
4 |
--------------------------------------------------------------------------------
/pages/jee/ejb/stateful.md:
--------------------------------------------------------------------------------
1 | # Stateful
2 |
3 | > TODO
4 |
--------------------------------------------------------------------------------
/pages/jee/ejb/stateless.md:
--------------------------------------------------------------------------------
1 | # Stateless
2 |
3 | > TODO
4 |
--------------------------------------------------------------------------------
/pages/jee/jpa.md:
--------------------------------------------------------------------------------
1 | # JPA
2 |
3 | ### Use `TypedQuery` instead of `Query`
4 |
5 | `TypedQuery` is just faster, and you don't need to cast.
6 |
7 | Bad:
8 |
9 | ```java
10 | Query q = em.createQuery("SELECT t FROM Type t where xyz = :xyz");
11 | q.setParemeter("xyz", xyz);
12 | List types = (List) q.getResultList();
13 | ```
14 |
15 | Better:
16 |
17 | ```java
18 | TypedQuery q = em.createQuery("SELECT t FROM Type t where xyz = :xyz", Type.class)
19 | .setParemeter("xyz", xyz);
20 | List types = q.getResultList();
21 | ```
22 |
23 | ### Use fluent interface in queries
24 |
25 | Good:
26 |
27 | ```java
28 | TypedQuery q = em.createQuery(
29 | "SELECT t FROM Type t where xyz = :xyz and abc = :abc", Type.class);
30 | q.setParemeter("xyz", xyz);
31 | q.setParemeter("abc", abc);
32 | List types = q.getResultList();
33 | ```
34 |
35 | Better:
36 |
37 | ```java
38 | List types = em.createQuery(
39 | "SELECT t FROM Type t where xyz = :xyz and abc = :abc", Type.class)
40 | .setParemeter("xyz", xyz)
41 | .setParemeter("abc", abc)
42 | .getResultList();
43 | ```
44 |
45 | ### Use `FetchType.LAZY` on relations
46 |
47 | Sometimes you need to relate two entities, and when you use annotations like `@ManyToOne` and `@OneToOne` the default property is `FetchType.EAGER`.
48 |
49 | * `EAGER` collections are fetched fully at the time their parent is fetched. Even if you don't need them
50 | * `LAZY` on the other hand, means that the collection is fetched only when you try to access them (It's LAZY hum?)
51 |
52 | There's a HUGE slow down performance when you use `EAGER`. Only use if you have a good reason to do.
53 |
54 | ```java
55 | @ManyToOne(fetch = FetchType.LAZY)
56 | private Client clients;
57 | ```
--------------------------------------------------------------------------------
/pages/patterns/gof.md:
--------------------------------------------------------------------------------
1 | # GoF
2 |
3 | > TODO
4 |
--------------------------------------------------------------------------------
/pages/patterns/jee.md:
--------------------------------------------------------------------------------
1 | # JEE
2 |
3 | > TODO
4 |
--------------------------------------------------------------------------------
/templates/links.html:
--------------------------------------------------------------------------------
1 |
2 | {{ page.section }}
3 |