简体   繁体   中英

What does the checkstyle warning “Declaring variables, return values or parameters of type 'ArrayList' is not allowed.” mean?

I wrote the following class.

package com.stackoverflow.examples;

import java.util.ArrayList;

/** RandomX. */
public final class Names {
    /** List of names. */
    private ArrayList<String> names = new ArrayList<String>();

    /** Constructor. */
    public Names() {
        this.names.add("Test");
    }

}

In the line with the declaration of names Checkstyle gives the warning:

Declaring variables, return values or parameters of type 'ArrayList' is not allowed.

How can I solve the problem, and what is the rationale behind this warning?

...what is the rationale behind this warning?

It's to encourage coding to the interface rather than to the concrete implementation. By declaring names as List<String> , you'll confine yourself to using List methods and not using anything specific that ArrayList provides on top of List .

In general , coding to interfaces is good practice. Like most rules, there are exceptions.

How can I solve the problem...

Declare names as List<String> , not ArrayList<String> :

/** List of names. */
private List<String> names = new ArrayList<String>();

It'll still be an ArrayList<String> , it's just that it'll be declared as a List<String> .

If you have a good reason that names must be declared as an ArrayList<String> , you can tell CheckStyle that you've made an intentional decision there by using a suppression annotation (or a suppression filter ). The annotation might be:

/** List of names. */
@SuppressWarnings("InterfaceIsType")
private ArrayList<String> names = new ArrayList<String>();

...but double-check that name, I don't know CheckStyle. I got the name from here .

Or of course, if you don't like that warning, just turn it off globally.

You should always program against Interfaces, not implementations.

ie even if you decide to use an ArrayList for a specific task, declare the variable to be a List, dto. for the return value. That allows you to replace the ArrayList with something else, without breaking your code.

Example: You return a List from a method:

public List<String> getNames() {
   List<String> = new ArrayList<String>();

   ...

   return result;
}

Later you decide that you need to protect the list of names against changes by the caller. You can change your implementation to:

public List<String> getNames() {
   List<String> = new ArrayList<String>();

   ...

   return Collections.unmodifiableList(result);
}

For the caller nothing changes, he still gets a List<String> . If your return value had been declared as an ArrayList<String> you would have not been able to make that change, or you would have to change the interface of your class, breaking the code of the calling classes.

You can take a look at this page .

The reason is that CheckStyle try to warn you about that is not a good practise to use concrete classes in variable declarations, return values or parameters.

You should use abstract clases or interfaces instead. This will reduce the coupling to that concrete clases.

尝试private List<String> names = new ArrayList<String>();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM