0

我下面有两节课。两者都有一个带有吸气剂的变量“回复”。这个变量没有setter方法。唯一不同的是在 ClassOne 中,变量是 static final。

那么有什么区别,哪个更受欢迎?

public class ClassOne {

    private static final String reply = "Success";
    ..

    public String getReply() {
        return reply;
    }

    // no setter

}

和第 2 类

public class ClassTwo {

    private String reply = "Success";
    ..

    public String getReply() {
        return reply;
    }

    // no setter
}

更新 1:

我想知道的是,当变量没有setter时,是否应该将该变量声明为static final以进行优化?还是没关系?

4

7 回答 7

5

是否应该将变量声明为 static final 以进行优化?

  • final当然,不仅是为了优化,也是为了清晰,因为它可以使你的对象不可变,这总是一件好事。

  • static完全改变了字段的性质,与 setter 的存在无关:您只需要该字段的一个实例,还是您的类的每个实例都需要一个?

  • 非静态示例: aPerson有一个名称,它是一个常量(对于给定的人 = 每个实例),因此您可以使用非静态 final 字段,在创建新字段时只设置一次Person

        private final String name;
  • 静态示例:当您没有 a 的名称时Person,您希望使用默认值 - 这是一个全局常量,在所有没有名称的人之间共享,您可以使用静态 final 字段:
        private static final String NO_NAME = "John Doe";
于 2012-09-13T09:17:13.733 回答
3

当您将变量设置为 final 时,您是在告诉所有人(编译器、运行时)它无法更改。这对优化有很大帮助,例如将所有出现的变量与其值内联。

于 2012-09-13T09:04:36.063 回答
2

将参考设置为final确保您无法更改参考。但是请注意,如果引用的对象是可变的,那么您仍然可以更改它(不是在这种情况下,因为字符串是immutable)。

我通常制作字段final并在构造函数中初始化它们。通过支持不变性,我的类更容易调试,并且在线程环境中更可能是安全的。删除不变性约束比添加它更容易。

我也为方法参数这样做。我很少(曾经)想要更改方法参数,并且将它们设为最终会捕获无意的分配。

我尽量使用static最终常量。除非它类似于记录器,否则我真的不希望每个类一个实例,并且(当然)这在多个类加载器的情况下不起作用。它也越来越接近单例反模式,这会影响简单的测试和(可能)线程。

于 2012-09-13T09:06:34.023 回答
2

当您有一个无法更改的常量字符串时,您应该将其设为静态最终字符串。

静态意味着类的实例需要更少的内存,因为实例不需要单独的副本。

Final 允许进行一些优化,从而使您的程序更快。

于 2012-09-13T09:06:45.053 回答
2

有几件事情要知道:

  • 编译器可以检查最终变量是否被意外更改。
  • 对非静态变量的引用包含在实例中,因此另外还有少量不必要的内存消耗
  • 静态变量在同一类的所有实例之间共享,因此您可以确保所有实例都使用相同的值
  • final 静态变量,尤其是字符串在编译时链接,因此它们不需要在运行时从字段中取消引用。由于即使通过反射也无法更改它,因为在运行时不使用此类字段。
于 2012-09-13T09:07:31.263 回答
1

您创建变量的事实static意味着该变量的单个实例将在 的所有实例之间共享ClassOne,因为该变量绑定到类本身,而不是其实例。除了任何 JVM 优化之外,reply每个ClassTwo.

于 2012-09-13T09:07:01.007 回答
1

第一个是Constant你需要在编译时知道它的价值。

private static final String reply = "Success";

第二个只是简单的成员变量。因此,任何情况下都首选第一个,因为第二个将为每个对象创造价值。

Assuming that you intended **private final String reply** in second case

最终变量只能通过初始化程序或赋值语句初始化一次。它不需要在声明时初始化:这称为“空白最终”变量。

在第二种情况下,您还可以在构造函数中声明和初始化它

 private final String reply;

你可以在这里阅读更多关于它的信息

于 2012-09-13T09:13:19.590 回答