2

私は Java の基本を知っており、今はEffective Java を読む旅に出ています。この本は、コンストラクターの代わりに静的ファクトリーメソッドを使用することを提案しています。だから私は次のようなGroovyコードを持っています:

public class Anto {
    public static void main(String[] args) {
            println Java.javaInstance()
        }
}

class Java {
    public static Java javaInstance() {
        return this
    }
}

これをコンパイルすると、次のようなエラーが発生します。

Caught: org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'class Java' with class 'java.lang.Class' to class 'Java'
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'class Java' with class 'java.lang.Class' to class 'Java'
    at Java.javaInstance(Anto.groovy:9)
    at Java$javaInstance.call(Unknown Source)
    at Anto.main(Anto.groovy:3)

どこで間違いを犯していますか?

4

4 に答える 4

3

を使用して実行できますreturn new Java();。静的メソッドは にアクセスできませんthis

編集:

通常、これらの静的ファクトリはシングルトンです。つまり、クラスのインスタンスを 1 つだけ使用する必要があります (通常、データベースへの接続など)。このディメンションをJavaクラスに追加する場合は、次のようにプライベート静的属性を使用します。

class Java {

    private static Java instance;

    public static Java javaInstance() {
        if(instance == null) {
            instance = new Java();
        }
        return instance;
    }

}
于 2012-05-04T07:34:21.090 に答える
2

静的ファクトリメソッドを使用するライブラリの良い例(Groovyに固有ではありませんが)は、GoogleGuavaです。Guavaは、このイディオムをさまざまな場所で使用しています。たとえば、それらのRangeクラスは9種類の範囲をサポートし、通常のコンストラクターを使用した場合、それらを区別するために使用できるのは引数だけであるため、いくつかのケースでそれらのシグネチャが競合します。

一方、静的メソッドは名前で区別することもできるため、Guavaは範囲のタイプごとに異なるメソッドを定義します。内部的には、これらのメソッドは通常のコンストラクターを呼び出しますが、公的にアクセスできるものではありません。

import com.google.common.collect.Ranges
import com.google.common.collect.DiscreteDomains

final dom = DiscreteDomains.integers()

assert [1,2,3,4,5] as Set == Ranges.closed(1, 5).asSet(dom)
assert [2,3,4] as Set     == Ranges.open(1, 5).asSet(dom)

これは便利なイディオムですが、通常のコンストラクターよりも自動的に優先されるイディオムではありません。通常のコンストラクターで十分な状況では、せいぜい必要以上のコードを記述し、最悪の場合、サブクラスを呼び出すことができるパブリックまたは保護されたコンストラクターが必要になるため、クラスの拡張が不可能になります。

于 2012-05-04T16:07:35.483 に答える
2

シングルトンを正しく作成すると(特にマルチスレッド環境では)間違いが起こりやすいため、独自のローリングを作成するよりも、Groovyに付属するシングルトンアノテーションを使用する方がよいでしょう。

public class Anto {
  public static void main(String[] args) {
    println Java.instance
  }
}

@Singleton
class Java {
}

Javaこれにより、クラスは次のように変換されます。

class Java {
  private static volatile Java instance
  private Java() {}
  static Java getInstance () {
    if( instance ) {
      instance
    } else {
      synchronized( Java ) {
        if( instance ) {
          instance
        } else {
          instance = new Java()
        }
      }
    }
  }
}
于 2012-05-04T08:03:23.977 に答える
0

メソッドはインスタンスメソッドではないthisため使用できません。static

特定のクラスの新しいインスタンスを作成するたびに、その新しいオブジェクト/インスタンスが独自の状態になります。this特定のインスタンスを指します。

シングルトンを作ろうとしていますか? クラスの単一のインスタンスが必要なだけですか?

class Singleton {
     //static reference to a particular instance
     private static Singleton instance;

     //private constructor so that it cant be called outside this class scope
     private Singleton();

     //synchronized in case your working in threaded enviroment
     public synchronized static Singleton getInstance()
     {
       if(NULL == instance)
       {
         instance = new Singleton();
       }
       return instance;
     }
}
于 2012-05-04T07:44:26.253 に答える