V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Registering
V2EX  ›  Java

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

  •  
  •   Registering · 2015-10-08 11:12:57 +08:00 · 5819 次点击
    这是一个创建于 3114 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Java 中,大家喜欢用

    public final static String val = "XXXX";
    

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

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

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

    个人理解。
    dullwit
        3
    dullwit  
       2015-10-08 11:27:15 +08:00
    那你觉得每 new 一个就+1 好,还是 only one 好!
    denger
        4
    denger  
       2015-10-08 11:28:34 +08:00
    通常使不使用 static 取决于这个 变量 /常量 是属于类 还是属于 对象,所以肯定不是为了通过类名访问而去使用 static ,只能说如果属于类的话,即可以通过类名去访问。
    dullwit
        5
    dullwit  
       2015-10-08 11:28:47 +08:00
    Registering
        6
    Registering  
    OP
       2015-10-08 11:31:15 +08:00
    @feilaoda 常量,抱歉,打错,,,,标题是写常量,帖子内容有一处写错成变量了
    cnhongwei
        7
    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
        8
    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
        9
    HentaiMew  
       2015-10-08 11:34:43 +08:00
    既然是常量就没必要作为成员变量,既然是静态且无法修改的 设置成公共的也无妨。
    iyangyuan
        10
    iyangyuan  
       2015-10-08 11:38:44 +08:00 via iPhone
    大哥这是常量,虽然常驻内存,没记错的话应该是在方法区中,但只有一份,如果不用 static ,每个实例都有一份,分配在堆中,一定意义上造成内存浪费。但我觉得没必要纠结这些。
    Registering
        11
    Registering  
    OP
       2015-10-08 11:39:54 +08:00
    @iyangyuan 嗯,是常量,,标题写常量,帖子内容打错成变量了。
    love
        12
    love  
       2015-10-08 12:09:19 +08:00
    你把程序所有 static 常量加一起也没有 100KB 吧,这点内存占用算个 P 啊
    WalkingEraser
        13
    WalkingEraser  
       2015-10-08 12:26:40 +08:00
    原因楼上童鞋们写了,不过想说我看过的大部分代码和以前 Google 及 stack overflow 到的,大部分人喜欢 public static final ...(逃
    initdrv
        14
    initdrv  
       2015-10-08 12:37:25 +08:00
    @silianbo
    写得好详细啊,感谢分享, mark !
    怎么打 @ 以后 没有自动提示了?还需手动写名字……
    varnotfound
        15
    varnotfound  
       2015-10-08 16:03:28 +08:00
    定义常量的主要目的是共享,如果不加 static 那么定义的这个常量就属于对象级别了,这样使用代价就变得高了
    可以用 jdk 自带的 javap 分别查看加上 static 和不加 static ,编译后的 class 对于内存的不同分配
    zacard
        16
    zacard  
       2015-10-08 16:29:14 +08:00
    不 static ,内存浪费的更多。。。
    lawrencexu
        17
    lawrencexu  
       2015-10-08 16:35:43 +08:00
    @WalkingEraser 这是 Java Language Spec 要求的,自然大部分代码必须遵循。
    songco
        18
    songco  
       2015-10-08 16:44:04 +08:00
    看来我每次面试的时候问这些基础问题还是有必要的..
    WalkingEraser
        19
    WalkingEraser  
       2015-10-08 17:49:01 +08:00
    @lawrencexu 下了好久,还没看☜(゚ヮ゚☜)
    skyyan
        20
    skyyan  
       2018-01-16 16:20:45 +08:00
    有没有试过 去掉 final 的表现呢
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3155 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 00:34 · PVG 08:34 · LAX 17:34 · JFK 20:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.