Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/387.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 最终(常量)实例(非静态)变量的行为是否与类(静态)变量类似?_Java_Variables_Scope_Constants - Fatal编程技术网

Java 最终(常量)实例(非静态)变量的行为是否与类(静态)变量类似?

Java 最终(常量)实例(非静态)变量的行为是否与类(静态)变量类似?,java,variables,scope,constants,Java,Variables,Scope,Constants,在下面的示例中,变量b声明为final,而不是static。这意味着它是一个常量实例变量。但是,因为它是常量,所以所有Passenger对象都不能更改其值。因此,将其声明为静态并将其作为类变量,以便所有实例化对象只使用一个副本,不是更好吗 class Passenger { int a; final int b = 0; void drive() { System.out.println("I'm driving!"); } } 这取决于b的目

在下面的示例中,变量
b
声明为
final
,而不是
static
。这意味着它是一个常量实例变量。但是,因为它是常量,所以所有
Passenger
对象都不能更改其值。因此,将其声明为
静态
并将其作为类变量,以便所有实例化对象只使用一个副本,不是更好吗

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

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

这取决于b的目的。通常,常量是为特定目的而存在的。如果将其设置为静态,则可能会在该类的某个实例中意外更改它,这将影响所有其他实例。

在java中,
static
属性基本上意味着:与类型本身相关联,而不是与类型的实例相关联

换句话说,您可以引用静态变量,而无需创建该类型的实例。。。然而,如果只使用
final
,则需要实例化该类


所以,是的,为了回答你的问题,我想说你是对的

静态变量的
最终变量的目的是具有对象范围的常数。它应该在构造函数中初始化:

class Passenger {
    final int b;

    Passenger(int b) {
        this.b = b;
    }
}
如果总是为
final
变量指定一个常量文本值(
0
),那么它就没有多大意义。最好使用
static
,这样您就只能拥有
b
的一个副本:

static final int b = 0;

顺便说一句,我不认为使用默认访问修饰符是您的意图。

如果您有多个
Passenger
类的实例,我会将其设置为静态。虽然这在谈论
int
变量时没有什么好处,但如果您有复杂的对象,这可以节省一些内存。这是因为静态变量属于一个类,而不是一个实例,因此它的内存空间只保留一次,它将由类对象本身引用,而不是由实例引用。当然,您应该知道,将
b
作为一个静态变量意味着对该变量所做的更改将反映在访问该变量的所有类上,但由于您将其设置为
final
,因此情况并非如此


还请注意,使用您编写的代码,与
Passenger
相同包中的类将能够通过
Passenger.b
访问
b
值(如果是静态的)。

A
final
原语与
static final
原语相同(但效率更高)

对不可变对象的
final
引用,与该对象的
静态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>();
对可变对象的
final
引用与对相同对象的
静态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>();
final int i=0;
//同
静态最终int=0;
最后一个字符串hi=“Hello”;
//同
静态最终字符串hi=“Hello”;
最终列表=新的ArrayList();
//不一样
静态最终列表=新的ArrayList();

最后一个例子唯一相同的时候是当你有一个单身的时候。编写单例时,由于差异不明显,通常会混淆静态和非静态字段和方法|

final变量是在您需要常量时定义的,因此您可以只指定一次值。
相反,使用
static
,您定义了一个由该类型的所有对象共享的变量(如全局变量),并且它与某个对象本身没有关联。

是的,您完全正确。但是静态变量也可以声明为final。这样可以防止意外修改。谢谢!没有想到构造函数中的对象范围常量和初始化。是的,我省略了本例中的访问修饰符。是的,为大变量节省内存正是我声明它为静态的原因。在这个例子中,我省略了访问修饰符。我怀疑很多人会注意到:当然,如果你有一个复杂的对象,记住只有引用才是最终的,但是除非你使它们不可变,否则你仍然可以通过操作方法来改变内部状态,如果有方法是公开的。这样,由于对象在所有实例之间共享,内部状态的变化将反映在该对象的所有读卡器上。哦,我明白你的意思了。