[JAVA] Points to worry about when handling variables personally

My main language is Java, so a personal summary of what I'm particularly concerned about in Java The interface and design are not mentioned in this article because the details are important.

point

Is the scope of the variable the minimum required?

The wider the scope, the more the variable plays. It also makes it easier to embed bugs such as use and changes at unexpected timings. I want to keep the scope to the minimum necessary.

Suppose you have a find method that queries a name from an array of IDs (int).

        String name;
        for (int id : identities) {
            name = find(id);
            //Something to do with name
        }

In this code example, the name variable is defined outside the loop, but if name is used only inside the loop, defining it inside the loop narrows the scope.

        for (int id : identities) {
            final String name = find(id);
            //Something to do with name
        }

Is the variable name appropriate for the scope?

Although it affects the scope mentioned above, the naming of variable names and method names needs to be stricter according to the scope. Conversely, a narrow scope eliminates the need for strictness.

Loop counters such as ʻint iare extremely short cases, but variables used within 2-3 lines can be simple variable names such asname and ʻage. On the other hand, constants need to be strict according to the domain. For example, public static final String DEFAULT_USER_NAME_VALUE =" Anonymous ";. If there is a type in ʻUSER`, the constant will increase by that amount, and the variable name will need to be stricter, which will make it longer.

If you want to use a variable that means some name inside or outside the loop, you'll need to do something like ʻuserName ʻadminUserName instead of a name like name and name2.

Is it immutable?

Variables can be immutable except for some counters. In the case of mutable variables, changes and namespace overwriting may occur at unexpected timings. Some IDEs, such as IntelliJ, even local variables are defined in final when the variable is created. However, be aware that the contents of Map and List can be rewritten even if the variables themselves are final. In the case of Java, it is desirable to return a deepcopy or ʻUnmodifiableList before returning a method that returns private final List`, which is an instance variable.

    private final List<String> nameList = new ArrayList<>();

    public List<String> getNameList() {
        return nameList;
    }

I would like to consider replacing this with the following.

    private final List<String> nameList = new ArrayList<>();

    public List<String> getNameList() {
        return Collections.unmodifiableList(nameList);
    }

Is it okay to use primitive constants?

I think there are many cases where String and int constants are used (although they are not primitives), but I would like to consider replacing them with enumeration types and classes that represent them. For example, suppose that there is a process to write data to a file, and the following constants are prepared as the write mode.

    /**
     *Addendum mode
     */
    public static final String WRITE_MODE_APPEND = "append";

    /**
     *Overwrite mode
     */
    public static final String WRITE_MODE_OVERWRITE = "overwrite";

    /**
     *New creation mode (error if there is a file)
     */
    public static final String WRITE_MODE_NEW = "new";

A write method using this mode would have the following signature:

public void write(String data, String mode)

Both the first and second arguments are String and it is difficult to distinguish without checking the argument name. Also, if mode is a string that is not supported because of String, it will be necessary to consider it.

For example, by using an enumeration type or Mode class, mistakes such as passing the original data as the second argument will not occur.

    enum WriteMode {
        /**
         *Addendum mode
         */
        APPEND,
        /**
         *Overwrite mode
         */
        OVERWRITE,
        /**
         *New mode
         */
        NEW;
    }

In this case, the signature would look like this:

public void write(String data, WriteMode mode)

Danger of "Well, for the time being"

It's a matter of course when you look at this alone, but when you code while verifying, there are still codes that say "Well, for the time being", or such code is included due to omission of refactoring. I want to be careful with my own caution as it may end up.

Recommended Posts

Points to worry about when handling variables personally
Perspectives to worry about when doing code reviews of web applications (Rails)
Summary of points I was worried about when migrating from java to kotlin
Points to review when Rubocop is slow to run
About exception handling
About exception handling
About Ruby variables
How to think when you suddenly understand about generics