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

时间:2018-03-06 12:09:50

标签: java constants static-import

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

因此,我在一个模块中创建了一个纯粹用于Strings的常量文件,该模块已经在项目中的每个其他模块中访问。

我的想法是,如果我们不断被警告这件事。它可能会多次创建这些字符串中的每一个并暂时增加内存。 (这是一个Web应用程序,生成JSON和XML,其中包含许多经常重复的术语,如“身份”或“社区”)

我想知道的问题是,我的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个。

首先我的问题是,哪个导入更有效,只需导入文件,导入每个必需的常量,或者它没关系那么多(文件中max绝对是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";

我已经为包名称加注星标以试图掩盖公司。即使这并不真正共享任何知识产权或秘密,也比抱歉更安全。

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

附加信息:我正在手动导入的每个文件之一,目前使用的每个文件都有22个导入这些常量。 我想如果数字达到这样的高度,那么也许我应该切换到*而不是?还是它还有记忆含义?

3 个答案:

答案 0 :(得分:2)

  

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

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

SonarLint警告的真正原因是拥有相同字符串文字的多个副本可能会导致维护问题。如果您想将"identityId"更改为"identityID",您可以在20个不同的位置进行更改...而且IDE不会提供太多帮助。

  

首先我的问题是,哪个导入效率更高,只需导入文件,导入每个必需的常量,或者它没那么重要

它对运行时性能没有任何影响,对编译速度的影响很可能是微不足道的。

import不同风格的最重要影响在于源代码的可读性,这主要是意见问题。

  

我的第二个问题是,这值得努力吗?

在你提出的例子中,绝对是一个意见问题。

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

最后,假设您决定使用String常量(这是一个好主意),我不建议将它们全部放入一个大的“常量”类中。根据其目的在普通的类和接口中定义它们。

答案 1 :(得分:1)

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

使用静态导入整个类的建议解决方案的问题在于,当您稍后阅读使用它们的源代码时,您不会知道常量的来源。这就是为什么它通常偏爱"静态导入"命名字段。但是如果你有250个这样的常量,你可能不想在你的文件中添加250个静态导入行。

不是命名常量PARAM_NAME_APPID等,而是将它们放在一个名为ParamNames的类中。然后你"静态导入"类名,这样你就可以看到它的来源,常量有不言自明的名字:

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

答案 2 :(得分:-1)

Constants类重构为属性文件。

然后它包含你的常量

PARAM_NAME_APPID=applicationId

您可以使用

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