用于存储简单数据的"public static"和"private static"之间的差异。什么更好?



什么是更好的解决方案?

我在想,究竟什么表现更好,还是哪个更"正确"?

public static List<String> globalUseVariable;

private static List<String> globalUseVariable;
public static List<String> getGlobalUseVariable() {
return globalUseVariable;
}

我认为第二个是因为封装规则?

简单来说:

  • 首先要避免静态
  • 也要避免暴露内部状态

拥有一个公共可写字段几乎是不可能的。如果允许多个组件更新该数据,则会导致直接的硬耦合。这也意味着你可以(很可能)对线程安全说"再见"。即使你认为"我今天只会阅读那个字段";也许你几周后就会忘记这件事。或者你团队中的其他人错过了这一部分。所以

因此,如果您有充分的理由向"公众"提供一些数据;那么至少使用吸气剂方法;因为这允许(稍后)进行更改。或者,它允许进行简单的增强,比如返回内部状态的副本/克隆(以防止"外部人员"以后操纵该内部状态)。

绕过静态的两种方法:

  1. 如果你真的需要全局状态,或者其他东西可以完成这项工作,请仔细思考
  2. 如果你需要全局状态,那么:A)创建一个接口,表示你想要提供的服务B)将该接口的实现创建为"正常"类C)然后使用一个也实现该接口的singleton(例如枚举)[现在singleton枚举可以将其工作委托给该impl类]

通过遵循方法2,您可以获得相同功能的东西(您有一个所有代码都可以使用的"全局"东西);但你会让事情更加脱钩;最重要的是:您可以在所有地方进行合理的单元测试。

静态通常是合理单元测试的"杀手"。

建议使用getter,因为您可能希望在不更改API的情况下更改类,或者您将决定在返回列表之前执行某种转换。看看这个关于类似情况的答案。在我看来,同样的原则通常适用于静态字段,实际上没有理由为它们破例。这个问题也涉及同一个主题。我认为这里概述的原因也适用于静态场,并且是完全合理的。

一般来说,如果你将某个东西公开,你就创建了一个公共的API,并应保证它不太可能更改,以避免以后出现严重的头痛问题(如果你正在创建一个公共库,并且必须向后兼容,则更改甚至可能是不可能的)。

此外,使用getter和setter,您可以确保您编写的代码是线程安全的,如其他答案和相关问题中所述。当您公开公共字段时,您对此无能为力。

哪个更"正确"?

就您的代码而言,我两者都不同意。将您的List标记为private,然后在方法中返回对同一List的引用,您将一无所获。您不能调用此封装,因为无论您在方法中添加什么逻辑,都会将List引用返回给调用者,以便根据需要进行修改。如果您想真正遵守封装,您至少可以要求您的方法返回一个不可修改的集合(使用Collections.unmodifiableList)。

如果您希望您的列表为public,那么您至少可以将其标记为final,这样类外的代码就不会尝试类似YourClass.globalUseVariable=null的操作,也不会破坏任何使用List的代码。

最新更新