静态导入文件或静态导入单个项目

Static Import file or static import individual items

我不确定我是对还是错,但 SonarLint 给了我无数关于重复使用某些字符串的警告。

因此,我在一个模块中创建了一个纯粹用于字符串的常量文件,该文件已在项目中的所有其他模块中访问。

我的想法是,如果我们不断被警告这件事。它可能会多次创建这些字符串中的每一个并暂时增加内存。 (这是一个网络应用程序,生成 JSON 和 XML 以及许多经常重复的术语,例如 "identity" 或 "community")

我想知道的问题是,我的 IDE (IntelliJ) 似乎一直在添加以下行:

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

而不是:

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

请记住,该文件目前很小,可能有大约 100 个常量,但这个数字最终会达到 250。

首先我的问题是,哪种导入效率更高,直接导入文件,导入每个需要的常量,或者没关系(文件中最大肯定是250个常量)

我的第二个问题是,这值得付出努力(简单但繁重的工作)吗? 一个例子是:

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

以上可能位于不同文件中的 3 或 4 个位置。 这两个常量的定义是:

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

最严重的罪犯如下。在从前端调用后端的每个方法中(在浏览器中发出 ajax 请求之后):

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));

同样的定义是:

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";

我给包裹名称加了星标,试图掩盖公司。即使这并没有真正共享任何 IP 或秘密,安全总比遗憾好。

感谢您提供的任何反馈(好的或坏的)。

附加信息:我正在为每个使用的文件手动导入的文件之一当前有 22 个导入这些常量。 我想如果这个数字达到这样的高度,那么也许我应该改用 *?还是它仍然有内存影响?

Constants class 重构为 属性 文件。

然后它像这样包含你的常量

PARAM_NAME_APPID=applicationId

您可以使用

加载它
Properties constants = new Properties();
try (FileReader reader = new FileReader("constants.properties")) {
    constants.load(reader);
}

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")

这实际上是错误的。在运行时,所有字符串文字都由 class 加载程序驻留。因此,如果您在许多不同的 class 中有 20 个 "identityId" 的示例,那么在运行时您将只有一个 String 对象来表示文字的所有副本。 (这不是实现细节。JLS 保证了这种行为。)

SonarLint 警告的真正原因是具有相同字符串文字的多个副本容易导致维护问题。如果你想将 "identityId" 更改为 "identityID",你有 20 个不同的地方可以更改它...... IDE 不会有太大帮助。

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

它对运行时性能的影响为零,对编译速度的影响很可能微不足道。

import 的不同风格最重要的影响是对源代码的可读性的影响,这在很大程度上是一个见仁见智的问题。

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

绝对见仁见智....在您提供的示例中。

但是,如果字符串是供用户阅读的消息,那么您可能需要将它们国际化。如果是这种情况,那么您最好将字符串存储在(例如)属性文件中......并根据用户的首选语言使用不同的文件。

最后,假设您确实决定使用字符串常量(这是个好主意),我不建议将它们全部放入一个大 "constants" class 中。根据它们的用途,在普通 classes 和接口中定义它们。

重复使用相同的文字字符串不会产生内存开销,因为 Java 源代码中的所有文字字符串都是 interned。 SonarLint 警告您不是因为内存效率低下,而是因为存在错误风险和可读性降低。

您提出的使用静态导入整个解决方案的问题 class 是,当您稍后阅读使用常量的源代码时,您将不知道这些常量来自何处。这就是为什么它通常比 "static import" 命名字段更受欢迎。但是如果你有 250 个这样的常量,你可能不想在你的文件中添加 250 个静态导入行。

不要将常量命名为 PARAM_NAME_APPID 等,而是将它们放在名为 ParamNames 的 class 中。然后你 "static import" class 名称,这样你就可以看到它来自哪里,常量有 self-explanatory 个名称:

static import package.name.ParamNames;
....
xxx = ParamNames.APP_ID;