有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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) 个答案

  1. # 1 楼答案

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

    private boolean running;
    

    。。。所以给定一个引擎实例,您可以调用引擎。正在运行()以检查状态

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

  2. # 2 楼答案

    在实例中,给定的变量值是默认值,表示null,所以如果是对象引用,则表示0,如果是和int

    局部变量通常不获取默认值,因此需要显式初始化,如果未能初始化,编译器将生成错误

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

  3. # 3 楼答案

    这不是一个肯定/否定的问题。这基本上取决于情况和你的需要。在尽可能小的范围内声明变量被认为是最佳实践。但是,在某些情况下(如本例中),根据任务的不同,最好在方法内部/外部声明它。如果您在外部声明它们,那么它将是一个实例,另一方面,它将是两个实例

  4. # 4 楼答案

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

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

  5. # 5 楼答案

    您的类名应该是Foo

    您拥有的两个版本不一样,这应该取决于您的用例

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

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

    另外,如果您想要第二个版本,请删除AClass aVar = new AClass();,只使用AClass aVar = doStuff();。因为您正在丢弃由new AClass();创建的第一个AClass对象