类级别实例化与方法实例化之间的区别

时间:2013-03-05 13:14:07

标签: java class variables

以下变量用法之间有什么区别

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”,那么哪个是更好的练习以及为什么。 在什么情况下可以使用。

6 个答案:

答案 0 :(得分:5)

这些实际上有着截然不同的含义。在案例1中,在构造b时分配A对象。它只构造一次(除非你从课外的某个地方重新分配它)。

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

答案 1 :(得分:0)

Class level instantiation将在创建类的新对象时实例化您的类变量。虽然method instantiation将在调用方法时实例化变量。

良好做法:当您的班级变量为/ {必须为Class level instantiation时,您应该instantiate in Constructorfinal或者使用method instantiation即{ {1}}

答案 2 :(得分:0)

Case 2:lazy initialization

有帮助

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;
}

答案 3 :(得分:0)

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

在第二种情况下,在调用doSomething()之前,b不会被初始化。

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

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

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

public class A {
  B b;

  public A() {
    b = new B();
  } 
}

答案 4 :(得分:0)

这里的真正区别在于,每次调用B时,您是否想要doSomething的不同实例?在第二种情况下,这是正确的,但如果有任何其他方法使用B,这也意味着您的类不是线程安全的。如果使用B在类中没有任何其他方法,为什么不将它作为方法范围的变量?

答案 5 :(得分:0)

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

public class Test{

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

我认为这可能对某些人有所帮助。