Things to be aware of when writing Java

I want you to write the code on the assumption that others will read it

I'm surprised that the code of the project I'm working on is too dirty. It was not originally written by us, but inherited the code manufactured by another company (super famous place). Hmmm, did you release the code written by the first grader without any code review? ?? Or is it written by someone who can only write in other languages (probably C ...?) And the code review is omitted below? ?? It's uselessly tricky, and isn't it working well in the first place? ?? ?? That is an honest impression. So I decided to refactor the entire class to be modified so that it wouldn't make sense to compare it with the original code, and rewrite all of JUnit. ... It seems that bugs will not be embedded by repairing ... In fact, after reading it in detail, I found a number of bugs. Well, JUnit is also full of holes, so it may be unavoidable. Well I was able to release it with this! ?? That's why I heard from the top that "Make materials for refactoring examples and trends together", so I'd like you to be aware of it when writing Java ♡. The content is fluffy and is for new programmers. I think veterans are probably doing it unconsciously. ** The headings are listed in the order in which they came up, not in order of priority. ** I want you to be aware of everything.

** Be aware from the beginning that the code you write at work is read not only by yourself but also by others **. And even if you write it yourself, it will be as difficult to read as someone else wrote it over time. Even if you take care of the release and defect handling, can you say that you can handle maintenance and repair by yourself until the end of the system?

** For projects that have coding conventions to follow, give them top priority. Observance of coding standards is the basic stance. ** **

Update history
  • 2018/12/18 -Added "[Variables and methods with wide scope without meaning are bad](# Variables and methods with wide scope without meaning are bad)"
  • 2018/12/20 -Added "[Names that cannot be understood are bad](# Names that cannot be understood are bad)" -"[Bonus 2 (references and reading materials)](# Bonus 2 (references and reading materials))" adds various references (maybe from now on)
  • 2019/03/26 -Added "[Unified coding style format is bad](# Non-unified coding style format is bad)" -Added "[Processing left in comment out is bad](# Processing left in comment out is bad)" -Added "[Gloss in declaration or assignment is bad](# Declaration or assignment is bad)"
  • 2019/09/19 --Added code examples and exceptional notes, and made various adjustments
  • 2020/02/25 -Added "[Reinventing the wheel is bad](#Reinventing the wheel is bad)" -Added "[Neglecting to update knowledge is evil](# Neglecting to update knowledge is evil)" --Other various reviews
Make fine adjustments that may not be necessary in the update history at any time.

Naming that cannot be understood is evil

** Insanely important. ** Directly leads to readability. The code written as a deliverable in business is basically read by anyone other than yourself. I will repair it. If you give it a name that you can't understand at that time, it usually gets stuck. ~~ I can't read it! I'm about to run out. ~~

Proper naming boosts readability

For example, suppose you declare three variables for String. Then, in the order of use, str1, str2, str3 …… What is str1 at first glance! ?? It will be. I only know the type. ~~ If you look at the declaration of the type, you can see it in one shot. ~~ It's the same as having no information. With such a name, you may not even know yourself a week later, let alone a month later. Isn't an engineer who can't even read the code he wrote too cool? ?? Give it a name that makes sense.

Java naming practices

Basically, in Java, the name is as follows. ** Follow the coding conventions, if specified. ** ** I often see it, but it's not good that the variable names are mixed with snake case and camel case. At least let's unify within the class. It's also not good to mix English and Romaji. Like "create Chohyo". You can use "create Report". Why do you make "forms" in romaji? Googling English words you don't understand. It is a variable that stores DB items, except for cases where the DB table definition is mixed with Roman characters.

--The class name is upper camel case (camel case with capital letters at the beginning) (also called Pascal format) --Ex: StringBuilder, IndexOutOfBoundsException, etc. --Method names and variable names are camelcase (lowercase letters at the beginning, lowercase letters at the beginning of connected words) --Ex: isEmpty, compareToIgnoreCase, etc. --The constant name is the upper snake case (connect words with underscores in all capital letters) --Ex: WEEK_OF_YEAR, DAY_OF_WEEK_IN_MONTH, etc.

Exceptional naming

If it is a very temporary variable with a short scope, it may be a string str or an int num. Variables for extended for loops. However, this is a story that is allowed only when the intent of the variable is easy to understand in a short scope, and basically it is better to name it properly. However, ** do not give originality to customary variable names with limited uses **. Specifically, Exception ʻe and ʻex in the try-catch clause, and counter variables ʻi and j` in the for loop. If they give you originality, readability will decrease. You can leave it as it is. And conversely, don't use customary variable names for variables of other uses or types.

There are many articles in Qiita about specific naming methods and tips. Try searching for something like "Java naming". Please read multiple articles in parallel. ** It's evil to feel like you understand just by reading a single article. ** **

Redundant or unreadable code is bad

Try to reduce the number of branches and make the naming according to the content. Even if you omit it, simple things that do not require comments are omitted. As you often see, declaring a variable for anything is less readable. If you store a value that requires only a short description that is referenced only once in a variable, the description that should be read increases accordingly. Especially if the scope is wide. If it is stored in a variable, it is often thought that the value is necessary because it will be referenced in the subsequent processing. In the case of method chains, method nesting, string concatenation, etc., where the description may be too long or complicated, I think it is better to store it in a variable appropriately considering the ease of debugging.

Common examples in beginner code

Even in one class, or even in one method unit, bugs are more likely to occur if the number of lines is large. In addition, the amount of simple testing increases and the man-hours increase. Readable code is often concisely organized. In other words, it's not a sloppy long code. Others can't read ~~ Unreadable ~~ Hard-to-read code is a hotbed of bugs. There is a high probability that the person in charge will see hell during an investigation or renovation (true face).

Boolean value judgment

It works as expected, but it is not correct to write "== true" and "== false" in the ** if statement **. Java's if statement only evaluates boolean values, so the bad example below is just garbage. What to do with nesting boolean judgments.

//Conditional judgment of redundant if statement
//Bad example
if (Condition A== true &&Condition B== false) {
}
//Good example
if (Condition A&& !Condition B) {
}

Variable declaration

Below are some common bad examples of variable declarations and value initialization. Making the assignment just overwriting the initialization a separate step is also meaningless and verbose code.

//Redundant variable declaration There is no point in simply overwriting the value at the time of declaration
//Bad example # 1 It is not always necessary to initialize with null
List<String> list = null;
list = new ArrayList<String>(Arrays.asList(new String[]{"ABC", "123"}));

//Bad example # 2 Initialization does not have to be new
List<String> list = new ArrayList<String>(0);
list = new ArrayList<String>(Arrays.asList(new String[]{"ABC", "123"}));

//Bad example # 3: There is no need to separate declaration and initialization
List<String> list;
list = new ArrayList<String>(Arrays.asList(new String[]{"ABC", "123"}));

//Good example: If you substitute, do not uselessly initialize at the same time as declaring
List<String> list = new ArrayList<String>(Arrays.asList(new String[]{"ABC", "123"}));

if branch optimization

Take the case where the assignment to the variable itself branches in connection with the above variable declaration and initialization. In that case, it makes sense to make the declaration and assignment a separate step, but if there are only two patterns, you can write only ʻif instead of ʻif ~ else. Even if there are 3 or more branches, consider optimizing the if statement. For enumerated branches, a switch statement is also useful.

//When the assignment itself branches(Only 2 patterns of branching)
//Redundant example
String str = null;
if (Condition A) {
  str = "ABC";
} else {
  str = "123";
}

//Example of deleting unnecessary branches
String str = "123";
if (Condition A) {
  str = "ABC";
}

//When using the ternary operator
String str =Condition A? "ABC" : "123";

If the derivation of the value to be assigned to condition A or str is not simple, the above code can be set to one line of String str = call another method;, so the return value will be another method with the value of str. I think it's good to do it. The pros and cons of using only one less complex process as a separate method may depend on the code reviewer. ** Unless prohibited by coding conventions **, it is also recommended to use the ternary operator when changing the value under simple conditions. However, the use of ternary operators should be limited to simple branches. If there are multiple conditions or if the conditions or branches are nested, readability will be reduced, so stop it.

Reinventing the wheel is bad

Don't implement existing features yourself. Its manufacturing and testing is a wasteful cost that you wouldn't otherwise have to pay. Far from being meaningless, it is a minus.

Common examples

I see it very often, but the apache.commons library is available, but only the standard API is used. You can see that the method is created by the combination of standard APIs even if the common class is cut off badly. Of course, I know that there are cases where the version of the commons library is low and there is no appropriate method, or the commons library cannot be used in the first place, and if so, it can't be helped. It is not good to voluntarily redevelop wheels that can be used but not used. It's also a bad idea to have a common class in your project and declare it there, but don't use it.

//Check if the string is null or empty
//Bad example
if (str == null || str.isEmpty()) {
}
//Good example
if (StringUtils.isEmpty(str)) {
}

//If the string is null or trimmed to an empty string, convert it to the specified string
//Bad example
String str = value;
if (StringUtils.isBlank(str)) {
    str = "Not set";
}
//Good example
String str = StringUtils.defaultIfBlank(value, "Not set");

//Object null check
//Bad example
if (obj == null) {
}
//Good example
if (Objects.isNull(obj)) {
}

Don't bother

It costs a lot to search the web and check if the function exists in the library you are using. However, the redevelopment of the wheel that takes care of it is a minus rather than a plus. Don't do it. Once you write the code, you have to test as much as you write. With existing features, you don't need to do detailed testing on that part. If it is a commons library, it is used all over the world, and it is almost guaranteed to work when there are no bugs. Rather, it's a great achievement to discover that it's used correctly and cause a bug and report it to the OSS community. It is a level that you can be proud of. But if you write it yourself, you have to test everything. No one guarantees the operation. But that test is useless. If you have a smartphone, you can look it up on your smartphone to find out the phone number of the store you want to go to on the go, right? You don't go into the telephone booth and pull the town page, right? You don't even call the directory assistance, right? That's it.

** Not knowing is not a bad thing. What's bad is that negligent attitude that you don't even know. ** ** At least let's check the inside of the project. ** Investigate yourself and then check with an expert. (Don't omit the process of checking by yourself) If the feature you need doesn't exist, you know it doesn't. If so, ask an expert whether to manufacture it as a common function or to describe it only in the part in charge of yourself. The commons library shown in the concrete example may not exist depending on the version. Even if a usage example is found by WEB search, there may be a method that does not exist in the version used in the project in charge. But that will increase your knowledge.

English documents are not scary

If you've tried to find out but Javadoc is hard to read in English, read the code directly. In many cases it is faster. The StringUtils class of commons doesn't say anything difficult. Most of the methods can be read even by beginners. Most of the method names are easy to understand. Let's open the jar code used in the project in charge directly in the IDE. If you're using Eclipse, it may be easier to find the feature you're looking for by using the outline view to sort the methods in ABC order.

It's not a school exam, so you don't have to translate it into Japanese. It would be nice if we could roughly translate and translate directly. I also rely on Google Translate. But if that makes sense, it's okay. Use what you can use. You can get the meaning just by browsing the words like that in the sentence. This is especially true of various exceptions. It's not good to just throw it before you do it.

It is evil to neglect to update knowledge

If you want to continue this work, updating your knowledge is essential. If you want to work only with the knowledge you have learned, this job is not suitable.

Get the knowledge you need for "now"

The libraries that can be used vary depending on the matter. You don't have to remember it all every time, but you need to look it up. Some people make it by brain death, but please stop it because it is nothing but the accumulation of technical debt. Do not stack code that should not be written. It's a tough word, but I want you to be able to refactor a lot of code every time you have a hard time analyzing it. (There are many such positions)

Java's date and time management has changed from Date and Calendar to LocalDateTime, right? File operations have become much easier with the advent of the java.nio.file package, right?

Recently, I've realized a new construction project after Java 8 where I don't see any try-with-resource, lambda expression, Stream API, or Optional. … The knowledge of the members has stopped. I think this pattern is often used in government offices and infrastructure contracts. But there should be new graduates as members. Since the surrounding code is legacy, I write legacy code. It's a bad trend. Until recently, I couldn't read Java 8-like code. Because there were only legacy code projects up to Java6. I couldn't catch up with the understanding even after reading the documents ... I couldn't do it without actually writing and moving it ... I can't remember the knowledge that I don't need to use ... However, I was assigned to a Java 8 project, so I was conscious of remembering it. Thanks to that, by the time half a month passed, I got used to the Stream API to the extent that I almost stopped writing for statements. This is Google teacher. Now that I can read Java 8 code, I can do more. Don't be afraid to see lambda-style sample code in your search results anymore. I don't have to turn right. (Lol) I'm happy how old I am to know what I don't know and to be able to do more.

Code that is difficult to unit test is bad

For example, JUnit test cases are hard to write code. Long and complex methods increase the cost of thinking and writing test cases. It is difficult to maintain and repair. Let's think about another description method for the same processing content, such as dividing the processing of the main method into small parts and dividing the divided processing into separate methods. I've seen that one public method of a completely new class has exceeded 300 lines due to the renovation, but I heard that it was a complaint from a customer. It's about Java in 2019. It's not an old C. Of course, the processing was deeply nested and the readability was very low. A level where only the person who wrote it can write JUnit. I was helped, but I couldn't do it without commentary from him. However, you should definitely stop the stupidity of removing the ** access modifier of a method split as private to call it in JUnit **. Make the test target incorrect for testing. Such a thing is nothing but a fall. I see it really often.

Use reflection when it cannot be called from the test class due to access modifier restrictions. Make the test target method protected and call it from the test class that inherits the test target class. protected is not an access modifier for testing purposes. Even private static methods can be called and tested by reflection ...

** Addendum 1 ** I wrote an article about a JUnit test class that calls a private method field. Test private methods in JUnit Refer to and set private variables in reflection

** Addendum 2 ** Access modifiers are a compulsory subject in Java, so if you're not sure, check them out. Some languages, such as JavaScript and Python, do not have access modifiers, but Java is a language that has access modifiers. I thought about why Python and JavaScript don't have access modifiers-Qiita

Nesting too deep is evil

As I wrote above, code with deep nesting (conditional branching and loop blocks have a multi-stage nested structure) is complicated and unreadable, and JUnit is also difficult to write. Such deeply nested code is also a sign that divides the process into separate methods. Code that doesn't consider readability is hard to test.

Early return, use of guard clause

For example, simple if nesting can be reduced by inverting the condition. In a common pattern, if the argument is not empty, it will be processed, but if it is empty, a fixed value will be returned. In that case, reverse the condition and describe so that the pattern that is not processed will exit the processing first.

//bad example
boolean result = false;
if (Condition A) {
  //Processing in case of condition A
  // ………
} else {
  return result;
}
return result;

//Good example
if (!Condition A) {
  return false;
}
boolean result = false;
//Processing in case of condition A
//After this, the return value will be returned when early return is possible.
// ………
return result;

The above result is the same. However, this alone reduces the number of nests in the processing performed within the block of condition A by one. If the block of condition A has multiple lines, the readability is also reduced because you do not know what to do other than condition A until you finish reading the block of condition A. Even when conditional branching is performed in a for statement, nesting can be reduced by continuing / breaking with this pattern. Also, in the bad case, the return value of else is a variable, so you can't tell at a glance what the return value is. There is no pattern other than false, so return false; is fine. Since there is no processing after return, it is not necessary to store it in a variable. It also narrows the scope of variables because you don't have to declare them before the if statement.

The same process described individually in multiple places is bad

What's wrong with writing the same process individually in multiple places? That is because maintenance and repairs are difficult. For example, suppose a process is performed in multiple places, but all are described individually. It was decided to repair the process. It is necessary to confirm, repair, and test with the same contents for all parts. In the case of the same description, it may be corrected by copying. If the number of corrections increases, copy-pemis will definitely occur. This is often the case with comments and variable name changes. In addition, it is necessary to check all the code for excess or deficiency in the execution location of the process. You can do it within the class, but if you don't make it common, you may end up checking the entire project. All of the repetitive costs are wasteful that you would otherwise be able to save.

Let's cut out the description that performs the same processing into one method. Values that differ depending on the call location can be passed as arguments. We recommend that you write code that works quickly and then refactor it. It's safer and more secure if you also write JUnit and confirm that the processing content is correct before refactoring. Once you've written it, it's easy to notice, "I feel like I wrote this process before ...?"

However, the above is for new manufacturing, and as an exception, it may be unavoidable to repair the existing system. For example, in an existing system in which the same process is described individually in multiple classes, some of the classes that should be shared include the class to be repaired. When modifying an existing system, it is often the case that parts that do not need to be changed are not modified as much as possible. This is because the modified class needs some retesting aside from the particle size and phase, which increases the man-hours for that. In such a case, even if it is a policy to perform refactoring that is not related to the repair content, in most cases, only refactoring within the class to be repaired is performed, and refactoring that cuts out a method common to another class is not performed. is. When refurbishing an existing system, check with your superior or expert about the availability and scope of refactoring.

It's best not to release (as much as possible) code that requires refactoring that would be a technical debt.

Variables and methods that are meaningless and have a wide scope are evil

Java is Java, not C, C #, or JavaScript

First of all, C language masters should forget about C language when writing ** Java. C language and Java are different things. ** ** Java and C may look a bit similar in appearance (coding style). But C and Java are different. The only difference is that the names of Java and JavaScript are similar. The contents are completely different. Please do not join. ** You can't write Java just because you can write C. ** Really don't mess with me. C is not object-oriented. It's a different thing. The only thing they have in common is their appearance. ** If an active wrestler and Kanna Hashimoto are wearing the same clothes, do you think they are the same person? Don't you? It's the same as that. ** **

If you declare a variable, where you use it

Don't declare variables together at the beginning of a method. Even if you use the IDE, ordinary local variables will only pop up as much as the type. If the declaration is far from the place where it is actually used, it will be a waste of time to go to see the declaration. ** As is often the case with people coming from C (or VBA), it's a bad practice in Java. ** ** Declare variables with the scope of use in mind. There is no point in writing variables outside the block that are only used inside the block. Rather, write it.

Occasionally, it's a project that still uses the old coding conventions, and it's written in a head-to-head declaration. But that's a fucking rule in Java today, so in some cases you should raise questions.

Be aware of the scope

Think of a scope as a usable range. In Java, variables declared inside a block cannot be used outside the block. (Block scope) For example, for statement like for (int i = 0; i <array.length; i ++) {, the loop counter "i" declared here will cause a compile error outside the for statement. It cannot be reused across for blocks. You only have to be aware of that variable in the block. Readability is greatly improved just by narrowing the range of awareness. Variables declared outside the block can be referenced and assigned even after exiting the block. it can. Yes, it's possible. You need to be aware of all the places where the variable is used because there is a possibility. The effective use of block scope is to make it explicit that it is used only there. It saves the reader's brain memory as well as the Java VM memory. So let's minimize the scope of variables.

Do not reuse variables

Reusing variables reduces readability and creates bugs. You need to be aware of everything where the variable is used. The reason why the heavy use of global variables is badly said is the difficulty of managing them. Where to substitute and where to refer. It's hard to keep track of everything. Also, there is a possibility that the value needs to be initialized when it is reused, but there is also a possibility that you forget to initialize it and create a bug. When reusing, variable names tend to be generic, but that's not good either. In other words, ** Reusing variables is harmful and worthless. ** It is an abbreviation that must not be omitted.

Forget about the old coding style

In the old days, variables used in a loop to save memory tended to be declared outside the loop. But now I don't have to worry about that much. If you use it only in a loop, declare it in a loop. If you declare it outside the loop, you'll forget that you have to initialize it every time at the beginning of the loop, and you'll bug bug! Well, on the contrary, there are also loop counters and variables that should be declared outside the loop.

Be aware of access modifiers

The same can be said for access modifiers as variables. Don't make any method or variable ** public or without access modifiers **. Touching from anywhere is not a benefit. In most cases, it's a disadvantage.

Simple copy and paste of code is evil

** Do not write code that you do not understand **. It's easy to create a situation where you don't know, but it works ... ** I don't know, so don't copy it **. Even when copying and pasting, it is essential to read it properly, understand the contents, and refactor the copy source code according to the paste destination.

Do not write code that cannot be explained to others!

Please keep in mind. When asked in a code review, ** you shouldn't write code that you can't explain yourself **. "Because I found it by searching" "Because there was a place written like this" etc ... These are not the reasons. Not an answer either. It's just an excuse. Don't copy and paste because of brain death, at least read and understand what you are doing. ** Get in the habit of reading Javadoc for APIs you don't understand **. Even if it is a method, please read about what kind of processing is done in that method. You cannot get experience points without reading.

References and answers are not equal

Occasionally (even if I'm not a newcomer), I ask "Tell me the reference code", and when I teach it, I copy the code as it is. You should look up the meaning of "reference" once in the dictionary. ** If only those people don't work, they will blame the person who taught them! !! !! !! !! !! !! !! !! ** ** Is your head a decoration? Ah? ** Take responsibility for your code, shit! !! !! !! !! ** It is an action that can not be helped even if it is cursed.

A method that is overloaded with processing is bad

Especially public methods. Writing test classes for long public methods can be extremely difficult. Be aware of 1 method 1 function. The test class is also easy to write. It's also easy to give a method name. You can call the private method from the private method, so try not to make it as complicated as possible. The less features you have, the shorter your code. I think it's best to fit at most 100 lines / method. Personally, I use the number of lines that can be displayed on one screen as a guide without scrolling.

Modifying a method that is overloaded with processing unnecessarily expands the scope of testing. If the three functions of processes A, B, and C are processed by one method, a test is required to confirm that processes B and C are not affected even if only process A is modified. Probably. Java is object-oriented, so it's a good idea to keep the single-responsibility principle in mind. [Single-responsibility principle | 97 things programmers should know](https://xn--97-273ae6a4irb6e2hsoiozc2g4b8082p.com/%E3%82%A8%E3%83%83%E3%82%BB%E3%82 % A4 /% E5% 8D% 98% E4% B8% 80% E8% B2% AC% E4% BB% BB% E5% 8E% 9F% E5% 89% 87 /)

It's easy to read if it's like calling the private method that performs each process in order in the public method. If the methods are separated for each process, the ease of testing will be greatly improved. Think of it as a plastic model. If you want to paint only the arm parts, it is easier to work if you can remove the arm parts. If it is a soft vinyl integrally molded figure, you need to be careful not to let the color stick out other than the arm.

Literals left with magic numbers are evil

Declare the same literal with similar intent as a constant to consolidate and make sense in one place. There is no reason to leave a value that is used with the same intent over and over again as a magic number. If it is named as a constant, "what is this value?" And "why is this value?" Is definitely reduced. Also, if you declare it as a constant and use it, when the value changes, you only need to change the constant value. If you use it in multiple places, it's a great advantage. Basically, it is not good to hard-code the magic number as it is.

However, making literals that are used only in one place at a time too much private constants also reduces readability, so there are some cases on a case-by-case basis. For example, if the variable name is zipCd and it is substring (0, 3) or substring (3). If this is the case, you can tell just by looking at the postal code being divided at the hyphen position. However, if it is a business value, it should be declared as a constant and used, or it should be a method for processing it.

If it's subject to change, it's a good idea to go out to an external properties file instead of a constant. You can make it meaningful by the key name when you get it from the property, and you don't have to modify the code.

** Added from the comment section ** If the values happen to be the same but have different uses and intentions, do not use common constants. It's a step towards bugs. If the purpose or intention is different, declare it with a different constant. It's important to think about what you name it as a constant.

Methods without Javadoc, Javadoc that does not match the code is bad

At a minimum, Javadoc with @param, @return, and @throws matching the source is required. Java is an IDE premise, and it would be nice if there was enough explanation to call that method after checking only Javadoc. Otherwise, you will have to read all the functions of the called party during maintenance and repair.

The cost of reading strange code written by others is quite high

For example, the @ param tag that explains the contents of the argument and the @ return tag that explains the return value. It is out of the question that there is no tag itself even though it is a method with arguments and return values, there are patterns such as @param str that are not explained by only the variable name (is it just automatically generated and left?) However, I apologize and want you to correct it immediately.

Still, it's still good if you can guess from the naming that the type is characteristic. If you say ʻint update (Connection con, String sql, Map <String, Object> params) , you can see at a glance that you pass the connection, SQL statement and parameters to be embedded in the SQL statement, update the DB and return the number. .. (** Javadoc description is still required, but **) But I can't guess what to pass for, what to do and what to return, a method like String edit (String str, String value, boolean flg)`. Perhaps the person who wrote it will not understand it over time. However, if Javadoc is written, the cost of reading the contents is almost unnecessary.

Javadoc should be updated from time to time

Javadoc is more than just written at the time of manufacture. Arguments and return values may increase, decrease, or change during refurbishment. In that case, please be sure to update. ** Javadocs that don't match the code are minus ** instead of zero. It's garbage. ~~ Should be thrown into the fire of hell. ~~ At least an overview, arguments and return values. Match these three with the code at that time. It's a good idea to get in the habit of reviewing the Javadoc whenever you write or modify your code.

Premise comments that exactly match the design document are bad

** Do not link comments with the design document, such as including the chapter number of the design document **. When modifying the design document, it is necessary to synchronize the comments of the code other than the modification target just because the item number has changed. There are many projects that do not maintain the design document (although it is strange that it is normal), and the code and the design document are steadily diverging.

~~ And at the time of renovation, it is said that "the design document is not reliable, so update the design document based on the code" and the man-hours will increase wastefully ...

Comments that are too detailed are bad

Uncomplicated processing and ** comments written one by one for each simple conditional branch are less readable **. Don't write code that halves the number of lines if you delete a comment. It is java.lang.String of the standard API that is often used, but please read it once. With Eclipse, you can jump to the source just by pressing F3. I don't think there are any detailed comments other than Javadoc.

Required comments, unnecessary comments

For example, do you need a condition or comment such as "when the number of items in the list is 0" that can be understood just by looking at the code? When writing a comment, think about whether you need it in the first place. Isn't it unnecessary to comment if you cut out to another method with a descriptive name even for complicated condition judgment? Code that does not require comments is easy to read.

Resources for writing comments

A large number of comments can be ridiculously modified when the code is modified. Furthermore, as the amount of comments increases, the number of erroneous comments that deviate from the processing due to omission of correction or copy / paste mistakes will increase. you must. I can affirm. Wrong comments are less readable than no comments. It is a hotbed of bugs.

Inconsistent coding style formats are bad

(Minimum) Unify within the file

Indented tabs and spaces, line breaks before and after the curly braces {}, spaces before and after operators and parentheses (), etc. Even if you do a grep search in the survey, it will not be caught unless you consider the number of spaces as a regular expression, and there is nothing good. If you are using an IDE, I think it has an automatic format function, so it's a good idea to set it to be formatted when you save it. If you share the settings that match the coding standards within the project, all members will have the same format. Since individual differences are less likely to occur, maintenance is easier.

Personally, I prefer the format to be set on a project-by-project basis. Even if the format isn't your preference. It's better than having to maintain or modify code in different formats for each file. As your eyes get used to it, it takes less time to research and read. Because the formats are complete.

Processing left in comment out is bad

It tends to be an old project that doesn't include version control. The culture of commenting out and leaving unrepaired code is only harmful, so don't do it. Please put version control into such a project.

Leave no trash

The intricacies of commented out and uncommented code can significantly reduce readability. Sometimes it was too complicated and I couldn't figure out where to uncomment because of the renovation like "Then uncomment the part that was commented out at the time of XX".

Don't leave code that isn't working right now. If you want to keep it, leave it in the version control history. Because you can check the difference. What is version control for ...

Alignment in declarations and assignments is bad

Coding styles and formats are like religions, so I thought I'd only say that I wanted them to be unified, but let me just say this. I think it's a bad code that doesn't have maintenance or refurbishment in mind.

For example, if you write it concretely, it's like this.

String name      = null;
String zip       = null;
String address   = null;
String telephone = null;
int    sex       = 0;

If you try to add a variable called "emailAddress" as a String and try to align it with spaces to match the existing format, the variable name of the "emailAddress" to be added will be the longest, so you have to align other lines as well. .. Or, if the type of "sex" is changed from int to BigDecimal, the type name is longer than String, so you have to put a space after the type name on the other line to align the digits. No, it may not be "must do", but non-uniform formats are not good. Why do people who like digit alignment deliberately put in trouble even if they take the trouble?

If you don't justify, you only need to add one line with String emailAddress = null; and change the type name and initial value with BigDecimal sex = null;. When doing a grep search, you don't have to write it in a regular expression considering that the number of spaces is variable, and you can't find the advantage of justification.

Does it improve readability? Let's improve readability in another place. While being maintained, some people will never align the digits somewhere. If you do not align the digits, you cannot force it unless a compilation error occurs. The person who wrote it may have written it in a monospaced font editor, while others may have written it in a proportional font. For example, there are quite a few cases where the code is pasted into Excel to create the material for the repaired part, but the default MS P Gothic is not the same width. It's hard to see because the digits are arranged irregularly rather than meaningless. It's strange to write code that even specifies the display font. Don't specify the format even though it's not rich text.

** Only the indents that represent the logical structure ** need to be aligned. (** Indent = indentation at the beginning of the line. Not included in the line **)

Well, if it is specified in the coding standard, it will be aligned while spitting blood. ** Absolute coding conventions. ** ** However, I personally don't like it. At least describe it in the formatter configuration file common in the project. Don't force a project that doesn't even have a config file.


Bonus 1 (mainly about comments in if statements)

I personally like it. About comments in if statements. I'd like you to stop putting line breaks and comments after the closing brace in the previous section of if-else or else. ** Java is not C #. ** ** I've actually created a bug in the past by modifying the code in the second example I hate below. I was asked to issue a disability vote. It's trauma anymore. If you see it, I want to get rid of it with all my might. I really hate it because it's hard to tell how far one if statement is. Do you need that comment in the first place? That's right. Also, if there are many conditional branches, I think it is better to consider making it an enumeration type and writing it with a switch statement.

Well, ** if the coding conventions are, you have to follow them **. .. ..

//Preferred example
if (Condition A) {
  //In case of condition A
} else if (Condition B) {
  //In case of condition B
} else {
  //Other than the above
}

//Disliked example 1
//In case of condition A
if (Condition A) {
}
//In case of condition B
else if (Condition B) {
}
//Other than the above
else {
}

//Disliked example 2
//In case of condition A
if (Condition A) {

//In case of condition B
} else if (Condition B) {

//Other than the above
} else {
}

Bonus 2 (references and reading materials)

Articles you want to refer to, interesting articles, interesting articles, etc. Please in your free time.

Amazing Java programming (let's stop) I laughed a lot. There are many cases that I often see in newcomers' code reviews.

Three major virtues of programmers I'm lazy and impatient, so I don't want to do simple tasks and I can't trust my eyes the most. So I learned Excel functions, VBA, regular expressions and SQL to let the PC do it. It is heavily used at the field level. The feeling of having fun is very important.

SE terminology in Wonderland My favorite article. I wonder why this is. When I notice it, I'm talking with this.

Recommended Posts

Things to be aware of when writing Java
Things to be aware of when writing code in Java
[Java] Things to be aware of when outputting FizzBuzz
Things to be aware of when using devise's lockable
[Java Silver] Things to be aware of regarding switch statements
To be aware of easy-to-read code
[Java] [Microsoft] Things to be aware of when including the JDBC driver for SQL Server in one jar
5 things new programmers should be aware of
[Java] Be aware of short circuits (short-circuit evaluation)
Java Servlet should be aware of multithreaded environment
[Beginner] Points to be aware of after Java exercises / Inheritance / Abstract method [Note 26]
Summarize the life cycle of Java objects to be aware of in Android development
Basic rules to be aware of to write easy-to-read code
[Rails] When using ajax, be aware of "CSRF measures".
[Java] When writing the source ... A memorandum of understanding ①
I want to be aware of the contents of variables!
Be sure to compare the result of Java compareTo with 0
[Technical memo] Things to be careful of from an engineer's point of view when creating a view
[Java] Input to stdin of Process
Java to be involved from today
Is it easy for the user to use when implementing general-purpose functions? Let's be aware of
[java] Summary of how to handle char
Basic knowledge of Java development Note writing
[Java] [Maven3] Summary of how to use Maven3
How to find the total number of pages when paging in Java
Output of the book "Introduction to Java"
Precautions when migrating from VB6.0 to JAVA
The story of writing Java in Emacs
[Java] When checking URL format with Bean Validation, it may be better not to use @URL of Hibernate Validator.
[Promotion of Ruby comprehension (1)] When switching from Java to Ruby, first understand the difference.
Summary of points I was worried about when migrating from java to kotlin
[Java] [Spring] Record of failure to enable Hibernate filter when instantiating Spring Data Repository
Use jenv to enable multiple versions of Java
[java] Summary of how to handle character strings
[Java] Number of connections required when nesting transactions
What surprised the Java shop when writing PHP
[Java] Summary of how to abbreviate lambda expressions
CORBA seems to be removed in Java SE 11. .. ..
Verification of performance impact when using Java volatile
[Java] Be careful of the key type of Map
Summary of moss when updating from JMockit 1.4 to 1.30
There seems to be no else-if in java
What I did when I converted java to Kotlin
Things to keep in mind when committing to CRuby
[Java] char type can be cast to int type
Minecraft BE server development from PHP to Java
[Java] How to get the authority of the folder
[Introduction to Java] Basics of java arithmetic (for beginners)
Java Welcome to the Swamp of 2D Arrays
Things to watch out for in Java equals
Settings to be done when changing from Sublime Text to VScode (when writing Ruby On Rails)
How to get the class name of the argument of LoggerFactory.getLogger when using SLF4J in Java
[Java] Introduction to Java
[Introduction to Java] List of things that got caught by the 14th day of programming
Introduction to java
[Java] Overview of Java
Summary of how to use the proxy set in IE when connecting with Java
[Java] How to get the URL of the transition source
When the hover of Eclipse is hard to see
Tomcat cannot be started due to java version change
Things to keep in mind when adding war to dependency