次のクラスがあります。
public class B
{
public A a;
public B()
{
a= new A();
System.out.println("Creating B");
}
}
と
public class A
{
public B b;
public A()
{
b = new B();
System.out.println("Creating A");
}
public static void main(String[] args)
{
A a = new A();
}
}
はっきりとわかるように、クラス間には循環依存関係があります。クラスAを実行しようとすると、最終的にはになりますStackOverflowError
。
ノードがクラスである依存関係グラフが作成された場合、この依存関係は簡単に識別できます(少なくともノードが少ないグラフの場合)。では、少なくとも実行時に、JVMがこれを識別しないのはなぜですか?スローする代わりにStackOverflowError
、JVMは実行を開始する前に少なくとも警告を出すことができます。
[更新]一部の言語は、ソースコードがビルドされないため、循環依存関係を持つことができません。たとえば、この質問と受け入れられた回答を参照してください。循環依存がC#の設計上の臭いである場合、なぜJavaではないのでしょうか。Javaが(循環依存のコードをコンパイルする)ことができるという理由だけで?
[update2]最近見つかったjCarder。Webサイトによると、Javaバイトコードを動的に計測し、オブジェクトグラフでサイクルを探すことにより、潜在的なデッドロックを検出します。ツールがサイクルを見つける方法を誰かが説明できますか?