简体   繁体   English

最终(常量)实例(非静态)变量是否像类(静态)变量一样?

[英]Do final (constant) instance (non-static) variables act like class (static) variables?

In the following example, the variable b is declared final , but not static . 在以下示例中,变量b被声明为final ,但不是static That means it's a constant instance variable. 这意味着它是一个常量实例变量。 However, because it's constant, none of the Passenger objects can change its value. 但是,因为它是常量,所以Passenger对象都不能改变它的值。 So isn't it better to declare it static and make it a class variable, so that there is only one copy to be used by all instantiated objects? 因此,将它声明为static并使其成为类变量不是更好,因此所有实例化对象只能使用一个副本吗?

class Passenger {
    int a;
    final int b = 0;

    void drive() {
        System.out.println("I'm driving!");
    }
}

The purpose of final but non- static variables is to have an object-wide constant. final但非static变量的目的是具有对象范围的常量。 It should be initialized in the constructor: 它应该在构造函数中初始化:

class Passenger {
    final int b;

    Passenger(int b) {
        this.b = b;
    }
}

If you are always assigning a constant literal value ( 0 ) to the final variable, it doesn't make much sense. 如果你总是为final变量赋一个常量字面值( 0 ),那就没有多大意义了。 Using static is preferred so that you are only having a single copy of b : 首选使用static ,以便您只拥有b的单个副本:

static final int b = 0;

BTW I don't think having default access modifier was your intention. 顺便说一句,我不认为有默认访问修饰符是你的意图。

It depends on the purpose of b. 这取决于b的目的。 Usually constants are there for a specific purpose. 通常常量是出于特定目的。 If you make it static you could accidentally change it in some instance of that class and that will affect all the others. 如果你将它设为静态,你可能会在该类的某个实例中意外更改它,这将影响所有其他实例。

If you have multiple instances of Passenger class, I would go for making it static. 如果您有多个Passenger类实例,我会将其设置为静态。 While this has little benefit when talking about an int variable, this could save some memory if you have complex objects. 虽然在讨论int变量时这没什么好处,但如果你有复杂的对象,这可以节省一些内存。 This is because a static variable belongs to a class, not to an instance, thus memory space for it will be reserved only once, and it will be referred by the class object itself, not by the instances. 这是因为静态变量属于一个类,而不属于一个实例,因此它的内存空间只保留一次,它将由类对象本身引用,而不是由实例引用。 Of course, you should be aware that having b as a static variable means that the changes made on this variable will be reflected on all the classes that access this variable, but since you made it final this won't be the case. 当然,您应该知道将b作为静态变量意味着对此变量所做的更改将反映在访问此变量的所有类上,但由于您将其设置为final因此不会出现这种情况。

Note also that with the code you've written, classes in the same package as Passenger will be able to read the b value by accessing it via Passenger.b (if static). 另请注意,使用您编写的代码,与Passenger相同的包中的类将能够通过Passenger.b (如果是静态的)访问它来读取b值。

A final variable is defined when you need a constant, so you can assign a value just once. 当您需要常量时定义final变量,因此您只需分配一次值。 Using static , instead, you are defining a variable shared by all the objects of that type (like a global variable) and it is not associated with a certain object itself. 相反,使用static来定义由该类型的所有对象共享的变量(如全局变量),并且它不与某个对象本身相关联。

In java, the static attribute basically means: associated with the type itself, rather than an instance of the type . 在java中, static属性基本上意味着: 与类型本身相关联,而不是类型的实例

In other words you can reference a static variable without creating instances of that type... Whereas in the case of just using final you'd need to instantiate the class. 换句话说,您可以引用静态变量而无需创建该类型的实例...而在仅使用final的情况下,您需要实例化该类。

So, yes, to answer your question, I'd say that you're right. 所以,是的,回答你的问题,我会说你是对的。 :) :)

A final primitive is the same as a static final primitive (except more efficient) final基元与static final基元相同(除了更有效)

A final reference to an immutable object the same as a static final reference of the same. final参考不可变对象相同的static final相同的参考。

A final reference to a mutable object is NOT the same as a static final reference of the same. 对可变对象的final引用与其相同的static final引用不同。

final int i = 0;
// same as
static final int = 0;

final String hi = "Hello";
// same as
static final String hi = "Hello";

final List<String> list = new ArrayList<String>();
// is NOT the same as
static final List<String> list = new ArrayList<String>();

The only time the last example is the same is when you have a singleton. 最后一个例子的唯一时间是你有一个单身人士。 It is fairly common for singletons to be written with a confusion of static and non static fields and methods as the difference is not obvious. 对于单身人士来说,编写静态和非静态字段和方法的混淆是相当常见的,因为差异并不明显。 :| :|

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM