有时候我会看到类似的东西:
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 final
或final
的原因
答案 0 :(得分:14)
我的讲话非常广泛,但如果它是最终的,那么你只需要它的一个实例,所以它通过使内存静止来节省内存。
更具体地说,final
关键字意味着无论变量存储都无法更改。这意味着一旦变量具有值,您可以使用该变量,但不能以任何方式对其进行修改。通常,要为最终变量赋值,请直接从声明final int variable = 12
开始。正如您所看到的,我在示例中使用了int,但您可以使用任何内容,包括引用变量。引用变量虽然很特殊,但是因为你不能改变变量指向的内容,但你可以改变Object本身(比如使用get / set方法)。
然而,归结起来的是,一旦你制作了一个最终变量,它就占据了内存中的空间。由于我们无法进一步修改此变量,为什么每次我们的Class实例化时都要重新创建它?我们使用static
关键字。这允许变量创建一次,并且只在内存中创建一次。
但是,有些特定情况下您不想使用static
并仅使用final。一个示例可以是时间敏感变量,例如存储对象实例化的时间。
答案 1 :(得分:3)
static
表示只会创建一个url_google
。如果它是一个实例字段(非静态),那么将为每个活动实例创建一个新的url_google
,而您实际需要的只是url_google
的一个副本。
答案 2 :(得分:3)
Java final
关键字非常松散地用于表示某些内容“无法更改”。
它与static
关键字无关,它表示它是一个“类变量”,意味着所有实例共享同一个变量副本。可以使用类直接访问类变量,而无需创建实例。
它们具有不同的含义,可以一起使用或单独使用。
答案 3 :(得分: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类,并且当创建另一个Circle对象时sNrOfCircles将改变时,它也不能被更改。
简单来说:如果它是一个Class属性(我们有多少个圆圈?),请使用static,如果初始化后值不会改变,则使用final(具有给定半径的圆的面积)并使用static如果两者都是最终的。
答案 4 :(得分:0)
主要原因是您无需实际的类实例即可访问该值。
在您的示例中,任何代码都可以访问url_google值,而无需MainActivity实例。