在任何函数之外为成员变量赋值是否被认为是好的做法?

时间:2013-02-08 00:45:25

标签: java styles

例如:

public class App {

   private Car car = new Car();

   public static void main(String[] args) {
       // TO DO
   } 
}

如果不好,有什么解决方案?你会如何重写这段代码?

9 个答案:

答案 0 :(得分:1)

在我看来,一切都取决于您正在使用的应用程序的设计。对于提供的示例,我认为这是可以接受的。但对于其他更确定的数据类型,我更喜欢构造函数初始化。主要是因为构造函数重载是可能的。

答案 1 :(得分:1)

我一直被告知你在上面声明并在里面初始化。初始化构造函数内部的东西更有效,因为如果需要在构造时使用传入的参数更改它,则在初始化时初始化和分配。

例如:

public class TestClass{
   //Declared but uninitialized
   Object obj;

   //Makes no difference but easier to read
   public TestClass(){
      this.obj = new Object();
   }

   //In this constructor however the object being passed in is what is initializing obj
   //-so if you were to initialize it above and then change it down here you are writing 
   //-to the mem twice and it is less efficient.  
   public TestClass(Object arg){
      this.obj = (Object)arg;
   }
}

对此的警告是,这些天的记忆真的很便宜。这样做的唯一真正目的(除了不想看起来像一个新手)是让其他人可以管理。

答案 2 :(得分:1)

如果程序“始终”需要对象的实例并且创建实例的成本不是太大(时间,资源),则可能会在声明中初始化对象。然后是的,可能需要这种“渴望初始化”。

然而,这种设计确实违背了OO设计,使类松散耦合并使单元测试更加困难。

在示例中:

public class App {
  private Car car = new Car();
}

你在说:

  1. App将“始终”需要Car对象。
  2. 在实例化App之后,将始终实例化Car。 (如果Car的实例化是昂贵的IE,这可能会有问题。它还有几个在实例化时创建的对象,比如说它从某种类型的远程调用中加载数据)
  3. 理想情况下,您只想在实际需要时创建对象。或者在构造函数(默认或重载)中提供一些灵活性。

    public class App {
        private Car car;
    
        App() {
        }        
    
        // overloaded constructor
        App(Car car) {
            this.car = car;
        }
    
        public void setCar(Car car) {
            this.car = car;
        }
    
        public Car getCar() {
            return car;
        }
    
        public static void main(String[] args) { 
            // default constructor, lightweight, no car initialization happening;
            App ap1 = new App();
    
           // Ok, now I want a car, and it should be red.
            Car redCar = new Car("red");
            ap1.setCar(redCar);
    
    
            // Using overloaded constructor, now I can control aspects of "car"
            Car blueCar = new Car("blue");
            App ap2 = new App(blueCar);
        }
    
    }
    

答案 3 :(得分:0)

如果您希望代码更容易测试,那么这是一种不好的做法。原因是,无论您是否愿意,创建App也会创建Car。现在,如果Car具有连接到数据库的代码,则oops,现在当您测试App时,您需要有可用的数据库,否则您的测试将失败。

解决方案是依赖注入,即控制反转。你会这样写:

public class App {

   private Car car;

   public App(Car car) {
       this.car = car;
   }

   public static void main(String[] args) {
       // TO DO
   } 
}

现在创建App并不一定会创建Car并且它们的耦合程度更低。

现在,我在这里非常迂腐。我可能一直在我的代码中使用你的例子。我只是指出了一个缺点。这并不总是坏事,并不总是好的。

答案 4 :(得分:0)

  私人汽车=新车();

这完全可以恕我直言。 这样做的几个原因:

  1. Car.<init>需要仅在App.init
  2. 中提供的参数
  3. App有许多字段,其他字段需要在App.<init>中初始化,并且为了保持一致性,您希望将它们保持在一起。
  4. 在任何情况下,请勿执行以下操作:

      

    私人汽车= null;

    因为每个java开发人员都知道实例字段被初始化为null

答案 5 :(得分:0)

除了tieTYT写的内容之外,可能值得考虑的是,如果你在构造函数中实例化所有成员,它会使它更具可读性。您可以通过阅读构造函数来学习有关该类型的新对象的所有知识。

答案 6 :(得分:0)

请注意:

之间的含义有所不同
public class App {

   private Car car = new Car();

   public static void main(String[] args) {
       // TO DO
   } 
}

public class App {

   private Car car;
   public App(){
     car = new Car();
   } 
}

例如,如果新的Car()在第一个失败,那么你肯定会有一个愉快的时间进行调试。如果需要,第二个更具可读性和可调试性。如果你认为字段是类的蓝图的一部分,那么在它们的声明中初始化它们是没有意义的。 既然你有这里的主要内容,这可能是你的切入点,但对于其他类,如果你把它们看作是对象的蓝图,那么构造函数的概念很有意义:

public class App{
  private Car car;
  public Car getCar(){
    return car;
  }
  public void setCar(Car car){
    this.car = car;
  }
  public App(Car car){
    this.car = car;
  }
}

我想,这是oop类最常见的结构。

答案 7 :(得分:0)

执行此代码的最佳方法是在main方法中创建一个类型为App的Object,它将调用Car类的构造函数。所以代码就是这样。

公共类App {

    private Car car;

    public static void main(String[] args)
    {
      App app=new App(); //
      app.car.  //Followed by the method or the member variable that you would like to
                //access

    } 

}

答案 8 :(得分:0)

使用Init()方法进行所有初始化。

公共类App {

private Car car;

public App() {
    this.car = null;
}

public void Init() {
    this.car = new Car();
}

public void Shutdown() {
    this.car = null;
}

public static void main(String[] args) {
    App app = new App();
    app.Init();
    app.Shutdown();
    app = null;
} 

}