2

有时我会看到类似的东西:

public class MainActivity extends Activity
{
    public static final String url_google = "http://www.google.com";

    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }    
}

我实际上没有得到的是为什么使用public static final, 而不是 public finalorfinal

4

5 回答 5

14

我说的很笼统,但如果它是最终的,那么无论如何你只需要它的一个实例,因此它通过使其成为静态来节省内存。

更具体地说,final关键字意味着不能更改任何变量存储。这意味着一旦变量有了值,您就可以使用该变量,但不能以任何方式修改它。通常,要为最终变量赋值,您可以直接从声明中进行,例如final int variable = 12. 如您所见,我在示例中使用了 int,但是您可以使用任何东西,包括引用变量。引用变量虽然很特殊,因为您无法更改变量指向的内容,但您可以更改 Object 本身(例如使用 get/set 方法)。

这归结为,一旦你创建了一个最终变量,它就会占用内存空间。既然我们不能进一步修改这个变量,为什么我们每次实例化我们的类时都要重新创建它?所以我们使用static关键字。这允许变量被创建一次,并且只在内存中创建一次。

但是,在某些特定情况下,您不想使用static并且只使用 final。一个示例可能是时间敏感变量,例如存储对象实例化的时间。

于 2012-12-09T20:24:32.830 回答
3

static意味着只会url_google创建一个。如果它是一个实例字段(不是静态的),那么url_google每个活动实例都会创建一个新的,而您实际需要的只是一个url_google.

于 2012-12-09T20:25:27.980 回答
3

Javafinal关键字非常松散地用于表示“不能改变”的东西。

它与表明它是“类变量”的关键字无关,static这意味着所有实例共享该变量的相同副本。类变量可以直接用类访问,而不需要创建实例。

它们有不同的含义,可以一起使用,也可以单独使用。

于 2012-12-09T20:26:25.057 回答
1

我认为 A--C 的回答具有误导性:“我说得非常笼统,但如果它是最终的,那么无论如何你只需要它的一个实例,因此它通过使其成为静态来节省内存。” 正如其他人指出的那样,他将静态和最终混合在一起,这是两个非常不同的东西。恕我直言,这不是广义的,但不够精确,尤其是在解释基本概念时。

静态变量与类相关联,而不是与任何对象相关联。类的每个实例共享一个类变量,该变量位于内存中的一个固定位置。任何对象都可以更改类变量的值,但也可以在不创建类实例的情况下操作类变量。

另一边的最终变量是只能初始化一次的变量。它们的值不必在编译时知道,但可以在运行时设置。如果最终变量是实例变量,则该变量可以有许多实例,所有实例都具有不同的值。

静态最终变量是一个常量,因为只有一个,并且一旦初始化就不能在运行时更改。在 Java 中,至少在编译时不必知道该值。

现在这都是非常理论的,所以让我们举一个例子来展示这些类型的变量的用途:

public class Circle implements Serializable {
    private static final long serialVersionUID = -1990742486979833728L;
    private static int sNrOfCircles;
    private final double mArea;

    public Circle(double radius) {
        sNrOfCircles++;
        mArea = radius*radius*Math.PI;
    }
}

serialVersionUID 将版本号与反序列化期间使用的 Circle 类相关联,以验证发送方和接收方是否已为该对象加载了与序列化兼容的类。serialVersionUID 永远不会改变,并且对于 Circle 的所有实例都是相同的。

sNrOfCircles 计算 Circle 实例的数量。它随着 Circle 的每个新实例而变化(而 serialVersionUID 从来没有)。

mArea 定义圆的面积。它也会随着 Circle 的每个实例而变化,但与 sNrOfCircles 相比,它与 Circle 对象相关联,而不是与 Circle 类相关联,而且它也不能被更改,而 sNrOfCircles 将在创建另一个 Circle 对象时发生变化。

简而言之:如果是 Class 属性(我们有多少个 Circles?),则使用 static,如果值在初始化后不会改变(具有给定半径的圆的区域),则使用 final,如果是,则使用 static final两个都。

于 2013-02-24T05:56:34.450 回答
0

主要原因是您无需类的实际实例即可访问该值。

在您的示例中,任何代码都可以访问 url_google 值,而无需 MainActivity 的实例。

于 2012-12-09T20:26:00.377 回答