Java中声明常量为什么用static修饰

在做Android开发的时候,只要查看一些Android源码,不难发现,其中,声明常量都是如下格式:

<span style="font-size:14px;">private static final String TAG = "FragmentActivity";</span>

声明为什么要添加static关键字呢?

之前是这么考虑问题的:定义一个类A,其中包含了用静态变量修饰的常量CONSTANT_A与直接用final修饰的常量CONSTANT_B

<span style="font-size:14px;">public class A {
    public static final String CONSTANT_A = "Hello";
    public final String CONSTANT_B = "Hello";
}</span>

在创建多个A的对象时,常量A在内存中只有一份拷贝,而B则有多个拷贝,后者显然使我们不希望看到的。

今天在看Android官网的时候,恰巧看到这一问题:

http://developer.android.com/training/articles/perf-tips.html

原文:

Use Static Final For Constants



Consider the following declaration at the top of a class:

static int intVal = 42;
static String strVal = "Hello, world!";

The compiler generates a class initializer method, called <clinit>, that is executed when the class is first used. The method stores the value 42 into intVal, and extracts a reference
from the classfile string constant table for strVal. When these values are referenced later on, they are accessed with field lookups.

在类第一次被执行的时候,编译器会生成一个初始化方法,这个方法将42的值存入对应的变量intVal,同时通过常量表获得strVal的一个引用。在之后引用这些变量的时候,将进行查询(表)来访问到。

We can improve matters with the "final" keyword:

通过使用final来提升性能:

static final int intVal = 42;
static final String strVal = "Hello, world!";

The class no longer requires a <clinit> method, because the constants go into static field initializers in the dex file. Code that refers to intVal will use the integer value 42 directly,
and accesses to strVal will use a relatively inexpensive "string constant" instruction instead of a field lookup.

这样,常量进入了dex文件的静态区初始化部分,不在需要一个初始化方法(来对变量赋值),代码中将直接使用42的常量值,strVal也通过开销低廉的“字符串常量”来代替文件查表。

Note: This optimization applies only to primitive types and String constants,
not arbitrary reference types. Still, it‘s good practice to declare constants static final whenever possible.

最有的一个小提示:这种右划仅对基本数据类型和String常量有效果,不包括其他引用类型。

看完Google的这段文章,虽然对里面部分名词还是稍有不解,但是了解到static final搭档的另外原因。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-03 00:38:09

Java中声明常量为什么用static修饰的相关文章

java中什么时候该用static修饰方法?有什么好处或者坏处?

当一个方法或者变量需要初始化加载,或者是经常被调用的时候可以加上static.用static修饰的方法可以用类名直接调用,不用的一定要先实例化一个对象然后才可以调用比如 person这个类里面有一个方法public static add(){}那么可以直接用person类调用 person.add();当然也可以用下面的方法先出一个对象在调用也是可以如果这个方法前面没有static 比如 public add(){}那么先要person p=new person();然后用p.add();类加载

日常总结の关于Java中的常量池技术

一.相关概念 什么是常量用final修饰的成员变量表示常量,值一旦给定就无法改变!final修饰的变量有三种:静态变量.实例变量和局部变量,分别表示三种类型的常量. Class文件中的常量池 简单讲解一下class文件的结构,开头的4个字节是class文件魔数,用来标识这是一个class文件,说白话点就是文件头,既:CA FE BA BE. 紧接着4个字节是java的版本号,这里的版本号是34,因为笔者是用jdk8编译的,版本号的高低和jdk版本的高低相对应,高版本可以兼容低版本,但低版本无法执

Java中定义常量方法及建议(Class/Interface)

Class定义常量方法(推荐方法) //final修饰符 public final class Constants { //私有构造方法 private Constants() {} public static final int ConstantA = 100; public static final int ConstantB = 100; ...... } 采用“类.常量名”方法进行调用.需要私有化构造方法,避免创建该类的实例.同时不需让其他类继承该类. 如果多处需要访问工具类中定义的常量

java中字符串常量,堆栈的区别和字符串函数intern()

转自:http://txy821.iteye.com/blog/760957 java.lang.String的intern()方法 "abc".intern()方法的返回值还是字符串"abc",表面上看起来好像这个方法没什么用处.但实际上,它做了个小动作: 检查字符串池里是否存在"abc"这么一个字符串,如果存在,就返回池里的字符串:如果不存在,该方法会把"abc"添加到字符串池中,然后再返回它的引用. 我们做个测试: Ja

Java中的常量如何避免反模式

在应用中,我们往往需要一个常量文件,用于存储被多个地方引用的共享常量.在设计应用时,我也遇到了类似的情况,很多地方都需要各种各样的常量. 我确定需要一个单独的文件来存储这些静态公共常量.但是我不是特别确定是应该用接口还是类(枚举不满足我的需求).我有两种选择: 使用接口,如: 1 2 3 4 5 package one; public interface Constants { String NAME="name1"; int MAX_VAL=25; } 或 1 2 3 4 5 pac

浅谈JAVA中字符串常量的储存位置

在讲述这些之前我们需要一些预备知识: java中的内存被分成以下部分: 1.栈区:由编译器自动分配释放,具体方法执行结束后,系统自动释放JVM内存资源. 其作用有保存局部变量的值,包括:1.用来保存基本数据类型的值:2.保存类的实例,即堆区对象的引用(指针).也可以用来保存加载方法时的帧. 2.堆区:一般由程序员分配释放,JVM不定时查看这个对象,如果没有引用指向这个对象就回收. 其作用为用来存放动态产生的数据,比如new出来的对象.注意创建出来的对象只包含属于各自的成员变量,并不包括成员方法.

在java中public void与public static void区别

static 方法可以被main方法直接调用,而非static方法不可以.因为static方法是属于类的,是类方法.可以通过类名.方法名直接调用.而非static方法必须等对象被new出来以后才能使用,因而不能在main中直接调用. public void 修饰是非静态方法,该类方法属于对象,在对象初始化(new Object())后才能被调用:public static void 修饰是静态方法,属于类,使用类名.方法名直接调用. Java 可以通过对象名调用静态方法(对象名.静态方法).Ja

Java中的常量和常量的表现形式及进制的转换

1.常量 在程序执行的过程中,其值不发生改变的量. 分类: (1) 字面值常量 字符串常量:用双引号括起来内容 字符常量:用单引号括起来的内容 整数常量:所有整数 小数常量:所有小数 布尔常量:true 或 false 空常量: null (2) 自定义常量(符号常量) 用final修饰变量(也就是常量) 2.常量的表现形式 Java针对整数常量提供了4种表现形式: 二进制 八进制 十进制 十六进制 3.进制的概述: 进制就是进位制,是人们规定的一种进位方法.几进制就是逢几进一. 计算机的电子原

Java中private、public、static、protetced、abstract、final

abstract (抽象的) 1.abstract可以修饰类和成员方法,被abstract修饰的类称为抽象类,被abstract修饰成员方法叫抽象方法.抽象类不一定有抽象方法,但拥有抽象方法的一定是抽象类; 2.被abstract修饰的类不能直接实例化,需要通过子类实现,所有抽象类一定有子类. 3.继承抽象类的子类必须重写抽象类中的被abstract修饰的抽象方法,如果不继承就必须把自己变成抽象的子类. final (最终的) final可以修饰类,成员变量,成员方法,局部变量/形参. 2.fi