3

例えば:

public class App {

   private Car car = new Car();

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

良くない場合、解決策は何ですか?このコードをどのように書き換えますか?

4

9 に答える 9

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

これに対する注意点は、最近のメモリは本当に安いということです。この方法でそれを行う唯一の本当の目的は(新人のように見えたくないことを除いて)、他の人がそれを管理できるようにすることです。

于 2013-02-08T01:35:48.077 に答える
1

私の意見では、すべては作業中のアプリケーションの設計に依存します。提供された例については、許容できると思います。しかし、他のより決定的なデータ型については、コンストラクターの初期化を好みます。主な理由は、コンストラクターのオーバーロードが可能であるためです。

于 2013-02-08T00:56:59.833 に答える
1

プログラムが「常に」オブジェクトのインスタンスを必要とし、インスタンスを作成するコストがそれほど大きくない場合 (時間、リソース)、宣言でオブジェクトを初期化することができます。そうです、このタイプの「熱心な初期化」が望ましいかもしれません。

ただし、この設計は、クラスを疎結合に保つという点で OO 設計に反し、単体テストが難しくなります。

例では:

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

あなたが言っています:

  1. アプリは「常に」Car オブジェクトを必要とします。
  2. アプリがインスタンス化された後、車は常にインスタンス化されます。(これは、Car のインスタンス化が高価な IE である場合に問題になる可能性があります。インスタンス化時に作成されるいくつかのオブジェクトもあり、たとえば、何らかのタイプのリモート呼び出しからデータをロードします)

理想的には、実際に必要な場合にのみオブジェクトを作成する必要があります。またはコンストラクター (デフォルトまたはオーバーロード) で、ある程度の柔軟性を提供します。

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

}
于 2013-02-08T05:06:39.423 に答える
0

このコードを実行する完璧な方法は、メインメソッドにAppタイプのオブジェクトを作成し、Carクラスのコンストラクターを呼び出すことです。したがって、コードは次のようになります。

パブリッククラスアプリ{

    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

    } 

}

于 2013-02-08T00:57:29.320 に答える
0

コードのテストを簡単にしたい場合は、悪い習慣です。その理由は、作成Appすると、Car必要かどうかに関係なく作成されるためです。さて、Carデータベースに接続するコードがある場合は、おっと、テストするときにApp接続できるデータベースを用意する必要があります。そうしないと、テストは失敗します。

解決策は、依存性注入、別名制御の反転です。あなたはそれをこのように書くでしょう:

public class App {

   private Car car;

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

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

現在、作成Appしても必ずしもが作成されるわけではなく、Car結合も少なくなります。

今、私はここで非常に衒学者です。私はおそらくあなたの例を私のコードでいつも使っています。欠点を指摘しているだけです。これは常に悪いことではなく、常に良いことでもありません。

于 2013-02-08T00:50:33.317 に答える
0

自家用車=newCar();

これは完全に大丈夫です。それをしない理由のいくつか:

  1. Car.<init>でのみ使用可能な引数が必要ですApp.init
  2. App多くのフィールドがあり、他のフィールドは初期化する必要がありApp.<init>、一貫性を保つためにそれらをすべて一緒に保持する必要があります。

いずれの場合も、次のことを行わないでください。

自家用車=null;

すべてのJava開発者は、インスタンスフィールドがに初期化されることを知っているからnullです。

于 2013-02-08T00:51:53.963 に答える
0

tieTYTが書いたこととは別に、コンストラクター内のすべてのメンバーをインスタンス化すると、コンストラクターが読みやすくなることを検討する価値があります。この型の新しいオブジェクトについて知る必要があるすべては、コンストラクターを読むことで学ぶことができます。

于 2013-02-08T00:52:38.240 に答える
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();
   } 
}

たとえば、最初に new Car() が失敗した場合は、それをデバッグするのが楽しくなります。2 番目は、必要に応じてはるかに読みやすく、デバッグ可能です。フィールドをクラスの設計図の一部と考えると、宣言でフィールドを初期化することはほとんど意味がありません。ここに main があるので、これがおそらくエントリ ポイントですが、他のクラスについては、それらをオブジェクトの設計図と考えると、コンストラクターの考え方は非常に理にかなっています。

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 クラスの最も一般的な構造だと思います。

于 2013-02-08T00:54:55.077 に答える
0

すべての初期化に Init() メソッドを使用します。

パブリック クラス アプリ {

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

}

于 2013-02-08T01:09:00.073 に答える