Java中本地变量和实例变量有什么区别?

20

除了作用域和存储差异外,在Java中,实例变量和局部变量之间还有其他重要的区别吗?


重复吗?https://dev59.com/1nI-5IYBdhLWcg3wj5FG - Alexander Pogrebnyak
4
除了差异之外,你想知道哪些差异?优化和寿命方面的差异还是其他方面的差异? - Fredrik
13个回答

45

我看到的主要区别在于:

作用范围:局部变量仅在声明它们的方法或块中可见,而实例变量可以被类中所有方法看到。

声明位置:局部变量在方法或块内声明,而实例变量在类内声明,但在方法外。

存在时间:当方法调用时,局部变量被创建并在方法退出时被销毁,而实例变量是使用new创建的,并在没有对它们的引用时由垃圾收集器销毁。

访问权限:您无法访问局部变量,而如果将实例变量声明为public,则可以访问。

声明位置:局部变量在调用之前在方法或块中声明,而实例变量可以在类级别的任何地方声明(甚至在使用后)。

实例变量总是有值的,即使代码没有赋值(那么它们将有null、0、0.0和false等值)。对于局部变量,必须通过代码赋值。否则编译器会生成一个错误。


你打算将“作用域”、“存在时间”和“声明位置”之间的区别是什么?此外,我不理解你的“访问”部分的意义——“访问”本地变量会意味着什么? - danben
@danben:对于局部变量来说,访问权限没有意义。这就是它与实例变量的区别所在。我同意这只是微不足道的差异,但仍然存在!同样的情况也适用于“它们被声明的位置”。至于作用域和存在时间(或生命周期),它们是完全不同的术语。我还忘记添加一个,现在我将进行编辑并添加。 - Alex Ntousias
@Alex 本地变量可以从其块中访问,包括从方法局部内部类中访问。这对您来说可能很明显,但是仍然说“您无法访问本地变量”似乎太武断了。 - Treefish Zhang

34

我能想到的另一件事:

实例变量会被赋予默认值,即如果是对象引用,则为null,如果是int,则为0。

而局部变量没有默认值,因此需要显式初始化(如果未能这样做,编译器通常会报错)。


10

另一个不同之处在于您不必担心对局部变量的并发访问;而在多线程环境中,您需要考虑实例变量的并发访问。


8

不,你已经几乎概括了它。一个实例变量属于类的一个实例,而局部变量属于堆栈帧。

实例变量被初始化为默认值,但通常最好使用显式初始化。


5

局部变量:

  • 声明在方法/构造函数内或代码块内(用花括号包围)
  • 必须在使用前初始化,否则无法编译。

实例变量:

  • 声明在类内部。
  • 初始化不是强制性的:如果省略,则包含默认值(0、0.0、falsenull等)。

2

-> 局部变量在方法体中声明,只能从声明点到方法结束时使用。

-> 实例变量在类中声明,但不在任何类方法的主体中声明。此外,实例变量可由类的所有方法访问。


1

除了已经提到的所有内容,我想指出本地变量对于JVM来说访问速度更快一些。与实例变量相比,JVM需要更多的工作来读取或写入实例变量。

对于当前的HotSpot服务器JVM仍然是正确的,因为这不是VM优化问题。这是由于实例变量在方法之外可见,因此在执行方法时可以从其他线程访问。


1
你能提供证明这是真的的参考资料吗?我怀疑读取最终的局部变量比读取最终实例字段更快。 - user2418306

1
除了之前回答中提到的所有差异,我想指出另一个差异,即实例变量可以有访问修饰符(如private、public、protected等),但局部变量将没有任何访问修饰符。

1

本地变量位于堆栈上,但成员变量(实例变量)位于堆上。


0

主要区别在于实例变量会获得默认值。例如,int 值为零,char 值为 null,但局部变量不会。

您可以保留未初始化的实例变量,但是局部变量必须初始化,否则会出现编译器错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接