2

私は、初期化が本質的にスレッドセーフではないという特性を持っていますが、定義により初期化スレッドセーフ であるコンパニオンオブジェクトのベースとして使用することを厳密に意図しています。

特性が常にコンパニオン オブジェクトによって拡張されることを (コンパイル時または実行時に) 保証する方法はありますか? トレイトには、コンパニオン オブジェクトの初期化中にのみ呼び出されるメソッドがあり、検証のサイトになる可能性があります。

4

2 に答える 2

1

次の解決策は、子クラスのコンストラクターの数をチェックします。これは、クラスには少なくとも 1 つのコンストラクターがあるのに対し、オブジェクトには 0 つのコンストラクターがあるという観察に基づいています。

チェックは実行時に行われます。

trait Y {
  // objects have 0 constructors, everything else has >= 1 constructors
  require(getClass.getConstructors.length == 0, "Trait Y should be extended by objects only")

  def hello(): Unit
}

class Foo$ extends Y {
  def hello() = println("Hello Foo$")
}

class Foo extends Y {
  def hello() = println("Hello Foo")
}

object Bar extends Y {
  def hello() = println("Hello Bar")
}

object Test extends App {
  new Foo().hello()  // exception is thrown
  new Foo$().hello()  // exception is thrown
  Bar.hello()  // prints Hello Bar
}
于 2015-01-10T03:33:05.030 に答える