4

以下变量用法有什么区别

public class A{

    B b= new B();

    public void doSomething()
    {
        b.callme();
    }
}

VS

public class A { 
    B b;
    public void doSomething() {
        b=new B(); 
        b.callme();
    }
}

如果我们在一个类中有一个“b”,那么哪个是更好的实践以及为什么。以及在什么情况下可以使用。

4

6 回答 6

5

这些实际上有非常不同的含义。在情况 1 中,b对象是在A构造时分配的。它只被构造一次(除非你从类外的某个地方重新分配它)。

在情况 2 中,您每次调用方法时都重新分配A's实例b

于 2013-03-05T13:18:44.133 回答
0

Class level instantiation当你的类的新对象被创建时,将实例化你的类变量。Whilemethod instantiation将在调用该方法时实例化您的变量。

良好实践:你应该做Class level instantiationinstantiate in Constructor当你的类变量是/必须是final,否则使用method instantiationielazy initialization

于 2013-03-05T13:17:05.593 回答
0

Case 2:有助于延迟初始化

In case 1的对象B是在您创建 的对象时创建的A。但是,如果创建B繁重的操作,那么您可以在实际需要 B 实例时懒惰地创建它。

Lazy Initialization当创建对象是一项繁重的任务并且您希望仅在实际使用对象实例时才延迟创建对象实例时很有帮助。但是请注意thread safety您的类是否在线程之间共享。

更新:但是在您的情况下,每次调用该方法时,您都会重新分配引用 b。这本身不是延迟初始化。

//example of lazy initialization
public B getB()
{
  if (something =  = null)
    b = new B();
  return b;
}
于 2013-03-05T13:17:11.433 回答
0

第一种情况称为内联初始化。它会在任何构造函数的主体运行之前但在调用超级构造函数之后发生。

在第二种情况下,直到 doSomething 被调用(),b 才被初始化。

至于哪个更好,这取决于你的程序逻辑。如果每次调用 doSomething 时都想要一个新实例,则第二种方法更好。如果您更喜欢延迟加载 b 然后将其修改为

if (b == null) b = new B(); 
return b;

就个人而言,为了可读性,我通常在构造函数中分配实例变量。

public class A {
  B b;

  public A() {
    b = new B();
  } 
}
于 2013-03-05T13:17:13.837 回答
0

这里真正的区别是你想要B每次doSomething调用不同的实例吗?在第二种情况下,这是真的,但这也意味着如果有任何其他方法使用B. 如果类中没有任何其他方法使用,B为什么不将其设为方法范围的变量呢?

于 2013-03-05T13:19:28.513 回答
0

我只是在尝试类似的场景,但由于一个错误,我创建了一个递归场景(StackOverflow 错误):-

public class Test{

Test t=new Test();
public static void main(String[] args) {
       Test t=new Test();
       System.out.println("Hello");
}
} 

我认为这可能对某些概念目的有所帮助。

于 2017-04-24T12:09:37.573 回答