【问题标题】:Is there any need to use "static" keyword for final variables in Java? [closed]Java中的最终变量是否需要使用“静态”关键字? [关闭]
【发布时间】:2021-08-04 02:44:40
【问题描述】:

我对 Java 中的 finalstatic 关键字感到困惑,需要澄清以下问题:

1. 对于变量,是否需要使用static?例如:

public final int ERROR_CODE = 200;

我认为没有必要使用static,如下所示。我错了吗?

public static final int ERROR_CODE = 200;

2. 据我所知,静态对于方法、类来说是有意义的,可以在不创建实例的情况下使用它们。 但是,在这个静态方法中也使用static 变量对于同时更改它们的值也很有意义:

public class MyClass {
    public static int myVariable = 0; 
}

//Now in some other code creating two instances of MyClass
//and altering the variable will affect all instances

MyClass instance1 = new MyClass();
MyClass instance2 = new MyClass();

MyClass.myVariable = 5;  //This change is reflected in both instances


3. 我可以更改最终关键字和静态关键字的顺序吗,例如

public static final int ERROR_CODE = 200; 

public final static int ERROR_CODE = 200; 

【问题讨论】:

  • 静态最终字段是属于该类的常量。非静态 final 字段在它所属的实例上是不可变的。

标签: java variables static constants final


【解决方案1】:

staticfinal 是不同的概念。 static 成员属于类而不是实例,而您不能重新分配 final 变量。

MyClass.myVariable = 5; //这个变化反映在两个实例中

➡️ 如果 myVariable 被声明为 final,这是不可能的。

我可以更改最终关键字和静态关键字的顺序吗?例如

public static final int ERROR_CODE = 200;或

public final static int ERROR_CODE = 200;

➡️ 是的。没什么区别。

【讨论】:

  • 除了我的第三个问题,其他的都没有完全理解。 #1中的意思是,如果我在公共类中定义一个final变量,是否需要使用static关键字?
  • 如果我在公共类中定义了final变量,是否需要使用static关键字? - 不需要。如果你声明为static,你可以访问它没有创建一个实例。但无论如何,您将无法重新分配它,即它的值无法更改。另一方面,如果是static 而不是final,则可以重新分配。他们之间没有任何关系。
  • 我的意思是同班。
  • @Jasmine - 你已经正确地称为final,但static 应该被称为same for all instances,因为它属于类,因此它的值对于所有实例都是相同的。
  • 完美!!!非常感谢。
【解决方案2】:

1:static 不是需要,只要该常量仅在实例内(或使用实例)访问。但是要在没有实例的情况下访问它,它必须是static。更重要的是,恕我直言,它应该是一个类变量,因为拥有一个常量(独立于实例)的实例变量是没有意义的 - 另请参阅下一点。

2:您描述的是功能-相关的类型,数据设计,数据模型,static 表示与实例成员相比的类成员(字段,方法)-OO 设计的重要部分

3:顺序并不重要...但是,Java Language Specification 建议

方法修饰符: (之一) Annotation 公共保护私有 抽象静态最终同步本机strictfp
...
如果两个或多个(不同的)方法修饰符出现在方法声明中,尽管不是必需的,但习惯上它们的出现顺序与上面 MethodModifier 产生式中显示的顺序一致。

【讨论】:

  • 最后的问题 :) #1 如果我们使用 final 变量作为常量,我们应该将它们定义为 static final 还是只定义为 final 来定义常量变量?更好的内存使用有什么区别吗?
  • #2 我们能否将final 描述为“分配一次”,将static 描述为“只是一个实例 b>" ?
【解决方案3】:

#1 用文字初始化非静态最终变量:

class MyClass {
   public final int ERROR_CODE = 200;
}

一个不好的做法,因为:

  1. 该类的每个实例都将拥有一个具有相同值的该变量的副本,因为它旨在用作全局常量,这会浪费内存。
  2. 静态访问常量是不可能的,所以MyClass.ERROR_CODE不会编译,如果你只需要这个值,你总是需要一个实例,例如new MyClass().ERROR_CODE

#2 静态变量

静态变量在多种情况下很有用,例如单例模式或与类相关的缓存,或者只是当您想在同一类的所有实例之间共享一些公共数据时

#3 是的

【讨论】:

  • 除了我的第三个问题,其他的都没有完全理解。 #1中的意思是,如果我在公共类中定义一个final变量,是否需要使用static关键字?
  • @Jasmine 如果您不将其设置为静态,那么变量将复制到每个实例,正如我所说,浪费内存。另请注意,在这种情况下,如果没有此类的实例,您将无法使用此常量
  • 最后的问题 :) #1 如果我们使用 final 变量作为常量,我们应该将它们定义为 static final 还是只定义为 final 来定义常量变量?更好的内存使用有什么区别吗?
  • #2 我们能否将final 描述为“分配一次”,将static 描述为“只是一个实例 b>" ?
【解决方案4】:

也许你的类还没有做到这一点,但类是一个对象,由类加载器管理。类加载器加载类并确保只有一个类对象。类对象是静态变量和方法所在的地方。

对于#1,静态意味着有一个变量属于该类。没有静态的声明意味着它是一个实例变量,并且您为该类创建的每个实例都有自己的变量。对于常量,将你的变量设为 static final,这样就只有一个了。

Final 表示值不变。如果变量是原始变量,则无法重新分配值。如果变量是引用类型,那么您无法更改变量指向的内容。如果指向的对象本身是可变的,final 不会改变它。

对于2,静态变量属于类,您的静态方法之一可以更改变量中的内容,其他方法可以看到更改。全局可变状态的推理令人困惑,而且您将 OO 的良好实践抛在脑后,进入了肮脏的黑客领域,因此在使用此功能时要非常谨慎。

#3:来吧,你可以在大约 10 秒内自己尝试一下。无论哪种方式都有效。 google style guide 建议“静态最终”。

【讨论】:

  • 最后的问题 :) #1 如果我们使用 final 变量作为常量,我们应该将它们定义为 static final 还是仅使用 final 来定义常量变量?更好的内存使用有什么不同吗?
  • #2 我们可以将final 描述为“分配一次”,将static 描述为“只是一个实例 b>" ?
  • @Jasmine:你可以坐在静态是每个类加载器的单个实例。 Final 在初始化时分配一次。
猜你喜欢
  • 2013-11-27
  • 2014-10-08
  • 1970-01-01
  • 2016-01-05
  • 2013-03-18
  • 1970-01-01
  • 1970-01-01
  • 2011-02-19
  • 1970-01-01
相关资源
最近更新 更多