Java 中使用 final static 这种方式定义常量的理由

2015-10-08 11:12:57 +08:00
 Registering

Java 中,大家喜欢用

public final static String val = "XXXX";

依稀记得 think in Java 中也有讲到。。

此处使用 final ,应该大家都知道原因,
但是此处用 static 是出于什么考量?仅仅是为了可以通过类名去访问?使用 static 的话变量基本就常驻内存了,这方面造成的损失怎么破,,,,

6094 次点击
所在节点    Java
21 条回复
feilaoda
2015-10-08 11:21:20 +08:00
你确信这是变量?
jiezhi
2015-10-08 11:25:52 +08:00
首先,如果静态方法中用到了该变量,那就必须 static 了;
其次,既然是全局变量,应该是做好随着类的生命周期存在的打算了吧,所以即使不用 static 关键字也应该是常驻内存的。

个人理解。
dullwit
2015-10-08 11:27:15 +08:00
那你觉得每 new 一个就+1 好,还是 only one 好!
denger
2015-10-08 11:28:34 +08:00
通常使不使用 static 取决于这个 变量 /常量 是属于类 还是属于 对象,所以肯定不是为了通过类名访问而去使用 static ,只能说如果属于类的话,即可以通过类名去访问。
dullwit
2015-10-08 11:28:47 +08:00
Registering
2015-10-08 11:31:15 +08:00
@feilaoda 常量,抱歉,打错,,,,标题是写常量,帖子内容有一处写错成变量了
cnhongwei
2015-10-08 11:32:39 +08:00
jvm 中专门有常量池来优化这些字符串的存储的,这点空间就不用你去费神了。如果是实例变量,其实也可能会使用到常量池。 scjp 中常考的 a = "abc"; b="abc";c = new String("adc"); println(a == b) ;println(a == c),你把这个运行一下就清楚了。
silianbo
2015-10-08 11:33:17 +08:00
好好看看 :局部变量、全局变量、静态变量 3 者之间的区别
简单来说就是一个引用问题!

final 修饰符只能够作用在类、方法和变量上。它的作用是所有被 final 修饰的内容不能被改变。如:

* final 类不能被继承。
* final 变量一旦被赋值就不能被改变。
* final 方法不能被重载。

注意:如果一个 final 变量是对象的引用,这意味着该引用的值是一定不会改变的,但是对象的成员值可以改变。
static 修饰符可以被应用在变量、方法、代码段和内部类中。如果需要 Java 实例变量被存储在单独的内存中,或需要变量对一个单独类的所有对象所通用,那么静态修饰符需要被应用在该变量的声明中。

* 静态方法: Java 的静态方法对类是通用的并且并不和 Java 实例相关联。尽管静态方法能够自由的访问类的静态数据和方法,但是它们并不能使用类的非静态功能。静态方法不能够被重载为非静态的。对于 Java 静态方法不能够使用 this 关键字。
* 静态块:静态代码块在类加载时只执行一次。
* 静态变量: Java 的实例变量使用单独的空间进行存储。如果需要变量对一个类的所有对象都是通用的,那么这个变量就需要被声明为静态的。类的所有实例对象都可以修改该类的静态变量。此外,使用对象实例修改静态成员并不是唯一手段,也可以直接使用 java 类来修改。静态变量也可以被 Java 对象的方法所访问。当一个常量的值在编译器就已经知晓了,它就需要使用 static 关键字来声明为 final 类型。
* 静态内部类:只有内部类能够使用 static 修饰符来声明,在 Java 中它被称为静态嵌套类。
HentaiMew
2015-10-08 11:34:43 +08:00
既然是常量就没必要作为成员变量,既然是静态且无法修改的 设置成公共的也无妨。
iyangyuan
2015-10-08 11:38:44 +08:00
大哥这是常量,虽然常驻内存,没记错的话应该是在方法区中,但只有一份,如果不用 static ,每个实例都有一份,分配在堆中,一定意义上造成内存浪费。但我觉得没必要纠结这些。
Registering
2015-10-08 11:39:54 +08:00
@iyangyuan 嗯,是常量,,标题写常量,帖子内容打错成变量了。
love
2015-10-08 12:09:19 +08:00
你把程序所有 static 常量加一起也没有 100KB 吧,这点内存占用算个 P 啊
WalkingEraser
2015-10-08 12:26:40 +08:00
原因楼上童鞋们写了,不过想说我看过的大部分代码和以前 Google 及 stack overflow 到的,大部分人喜欢 public static final ...(逃
initdrv
2015-10-08 12:37:25 +08:00
@silianbo
写得好详细啊,感谢分享, mark !
怎么打 @ 以后 没有自动提示了?还需手动写名字……
varnotfound
2015-10-08 16:03:28 +08:00
定义常量的主要目的是共享,如果不加 static 那么定义的这个常量就属于对象级别了,这样使用代价就变得高了
可以用 jdk 自带的 javap 分别查看加上 static 和不加 static ,编译后的 class 对于内存的不同分配
zacard
2015-10-08 16:29:14 +08:00
不 static ,内存浪费的更多。。。
lawrencexu
2015-10-08 16:35:43 +08:00
@WalkingEraser 这是 Java Language Spec 要求的,自然大部分代码必须遵循。
songco
2015-10-08 16:44:04 +08:00
看来我每次面试的时候问这些基础问题还是有必要的..
WalkingEraser
2015-10-08 17:49:01 +08:00
@lawrencexu 下了好久,还没看☜(゚ヮ゚☜)
skyyan
2018-01-16 16:20:45 +08:00
有没有试过 去掉 final 的表现呢

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/226257

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX