共享实例变量与局部变量

时间:2015-08-12 17:45:40

标签: java

是否有理由更喜欢在类与局部变量中使用共享实例变量并让方法将实例返回给它?或者是一个不好的做法?

import package.AClass;

public class foo {
    private AClass aVar = new AClass();

    // ... Constructor

    public AClass returnAClassSetted() {
     doStuff(aVar);

     return avar;
    }

    private void doStuff(AClass a) {
     aVar = a.setSomething("");
    }
}

VS。

import package.AClass;

public class foo {

    // ... Constructor

    public AClass returnAClassSetted() {
     AClass aVar = new AClass();
     aVar = doStuff();

     return aVar;
    }

    private AClass doStuff() {
     AClass aVar1 = new AClass();
     aVar1.setSomething("");

     return aVar1;
    }
}

第一个在很多方面对我更有意义,但我经常看到第二个代码。谢谢!

5 个答案:

答案 0 :(得分:2)

实例变量由类中的所有方法共享。当一种方法更改数据时,另一种方法可能会受其影响。这意味着您无法自己理解任何一种方法,因为它受到类中其他方法中的代码的影响。调用方法的顺序可能会影响结果。这些方法可能不是可重入的。这意味着如果在完成执行之前调用该方法(比如它调用一个然后调用它的方法,或者触发一个事件然后监听器调用该方法),那么它可能会失败或表现不正确,因为数据是共享。如果这不是足够的潜在问题,当你有多线程时,数据可能会在你使用时被更改,导致不一致和难以重现错误(竞争条件)。

使用局部变量可以将范围最小化到需要它的最小代码量。这使得它更容易理解和调试。它避免了竞争条件。确保方法是可重入的更容易。最小化数据范围是一种很好的做法。

答案 1 :(得分:0)

这不是肯定/否定的问题。这主要取决于具体情况和需求。尽可能在最小范围内声明变量被认为是最佳实践。然而,可能存在某些情况(例如在这一情况下),根据任务,最好在方法内/外声明它。如果你在外面声明它们将是一个实例,另一方面它将是两个实例。

答案 2 :(得分:0)

实例属性表示该类的特定实例的状态。考虑一个具体的例子可能更有意义。如果类是Engine,则可能表示Engine状态的其中一个属性可能是

private boolean running;

...所以给定一个Engine实例,你可以调用engine.isRunning()来检查状态。

如果给定属性不是类的状态(或组合)的一部分,那么它可能最适合作为方法中的局部变量,作为实现细节。

答案 3 :(得分:0)

您的班级名称应为Foo

你拥有的两个版本不一样,它应该取决于你的用例。

当不同的调用者使用相同的AClass对象调用returnAClassSetted()方法时,第一个版本返回相同的Foo对象。如果其中一个更改了返回的AClass对象的状态,则所有对象都将看到更改。您的Foo课程实际上是Singleton

每次调用者使用相同或不同的AClass对象调用returnAClassSetted()方法时,第二个版本都会返回一个新的Foo对象。您的Foo课程实际上是Builder

此外,如果您需要第二个版本,请移除AClass aVar = new AClass();,然后使用AClass aVar = doStuff();。因为您丢弃了由AClass

创建的第一个new AClass();对象

答案 4 :(得分:0)

在实例变量中,给定的值是默认值,表示null,因此如果它是对象引用,则为0,如果是和int。

局部变量通常不会获取默认值,因此需要显式初始化,如果不这样做,编译器会生成错误。

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