javaconstantsstatic-import

Static Import file or static import individual items


Whether I am right or wrong about this I am not sure but SonarLint gives me countless warnings about the repeated use of certain strings.

As a result, I created a constants file purely for Strings in a module that is already accessed in every other module in the project.

My thought was if we are continually being warned about this. It's probably creating each of these strings multiple times and temporarily increasing memory. (It's a web app, generating JSON and XML with many frequently repeated terms such as "identity" or "community")

The question I am wondering is, my IDE (IntelliJ) seems to just keep adding the following line:

import static com.*****.*****.resources.Constants.*

Instead of:

import static com.*****.*****.resources.Constants.PARAM_NAME_HASEMAIL;
import static com.*****.*****.resources.Constants.PARAM_NAME_HASSMS;
import static com.*****.*****.resources.Constants.PARAM_NAME_CMD;

Bearing in mind the file is currently small with maybe around 100 constants, but that figure will eventually reach 250.

First of all my question is, which of the imports is more efficient, just import the file, import each required constant, or it doesn't matter that much (max will definitely be 250 constants in the file)

The second question I have is, is this worth the effort (easy but grunt work)? One example is:

data.has(PARAM_NAME_OPTIN)
data.remove(PARAM_NAME_OPTIN);
data.put(PARAM_NAME_OPTINTYPE, Coupon.OPTIN_MODE_SINGLE_OPTIN);

The above is in maybe 3 or 4 locations in different files. The definitions of those 2 constants are:

public static final String PARAM_NAME_OPTIN             = "optin";
public static final String PARAM_NAME_OPTINTYPE         = "optInType";

The worst offender is below. It is in every single method that makes a call to the backend from the front end (following an ajax request in the browser):

json.put(PARAM_NAME_CMD, "Coupon.doSearchCouponEntriesByCoupon");
json.put(PARAM_NAME_APPID, PARAM_NAME_CAMPAIGN);
json.put(PARAM_NAME_COMMUNITYID, session.getAttribute(PARAM_NAME_COMMUNITYID));
json.put(PARAM_NAME_IDENTITYID, session.getAttribute(PARAM_NAME_IDENTITYID));

Again the definitions are:

public static final String PARAM_NAME_APPID             = "applicationId";
public static final String PARAM_NAME_CMD               = "command";
public static final String PARAM_NAME_CAMPAIGN          = "*****campaign";
public static final String PARAM_NAME_COMMUNITYID       = "communityId";
public static final String PARAM_NAME_IDENTITYID        = "identityId";

I have starred the package names to try to obscure the company. Even if this doesn't really share any IP or secrets, better safe than sorry.

I appreciate any feedback you give (good or bad).

Additional info: one of the files I am doing the import manually for each one used currently has 22 imports for those constants. I guess if the number reaches such heights, then maybe I should switch to the * instead? Or does it still have memory implications?


Solution

  • My thought was, if we are continually being warned about this. It's probably creating each of these strings multiple times and temporarily increasing memory. (It's a web app, generating JSON and XML with many frequently repeated terms such as "identityId" or "communityId")

    That's actually wrong. At runtime, all string literals are interned by the class loader. So, if you have 20 examples of "identityId" in many different classes, at runtime you will have only one String object that represents all copies of the literal. (This is NOT an implementation detail. The JLS guarantees this behavior.)

    The real reason for the SonarLint warnings is that having multiple copies of the same string literal is liable to cause maintenance problems. If you want to change "identityId" to "identityID", you have 20 separate places to change it ... and the IDE is not going to be a lot of help.

    First of all my question is, which of the imports is more efficient, just import the file, import each required constant, or it doesn't matter that much

    It has zero impact on runtime performance, and the impact on compilation speeds is most likely insignificant.

    The most significant impact of the different styles of import is on the readability of your source code, and that is largely a matter of opinion.

    The second question I have is, is this worth the effort?

    That is definitely a matter of opinion .... in the examples that you presented.

    However, if the strings were messages for users to read, then you may need to internationalize them. If that is the case, then you will be better of storing the strings in (for example) a properties file ... and use different files depending on the user's preferred language.

    Finally, assuming that you do decide to use String constants (which is a good idea), I wouldn't recommend putting them all into a big "constants" class. Define them in ordinary classes and interfaces, according to their purpose.