Java FAQ:スーパークラスの引数なしコンストラクタがないとコンパイルエラーになる場合
Java FAQ:S010 Q-03
話がちょっとややこしい?
と、思ったのは、デフォルトコンストラクタを勘違いしていたからのようだ。
「クラスの定義にコンストラクタを一つも記述しなかった場合、コンパイラによって自動的に引数なしのコンストラクタが生成されます。」の「一つも記述しなかった場合」を分かっていなかった。
class C2008041411 { //C2008041411() { // System.out.println("C2008041411"); //} C2008041411(String str) { System.out.println("C2008041411: " + str); } } class C2008041412 extends C2008041411 { C2008041412(String str) { System.out.println("C2008041412: " + str); } } public class C2008041410 { public static void main(String[] args) { new C2008041412("foo"); } }
をコンパイルすると、以下のエラー。
エラーが分かりにくいけど、「コンストラクタ C2008041411() が見つからない」ということなんだろう。
C2008041410.java:13: シンボルを解釈処理できません。 シンボル: コンストラクタ C2008041411 () 位置 : C2008041411 の クラス C2008041412(String str) { ^ エラー 1 個
class C2008041421 { C2008041421() { System.out.println("C2008041421"); } C2008041421(String str) { System.out.println("C2008041421: " + str); } } class C2008041422 extends C2008041421 { C2008041422(String str) { System.out.println("C2008041422: " + str); } } public class C2008041420 { public static void main(String[] args) { new C2008041422("foo"); } }
で、
C2008041421 C2008041422: foo
C2008041422 に対し、javap -c を実行
Compiled from C2008041420.java class C2008041422 extends C2008041421 { C2008041422(java.lang.String); } Method C2008041422(java.lang.String) 0 aload_0 1 invokespecial #1 <Method C2008041421()> 4 getstatic #2 <Field java.io.PrintStream out> 7 new #3 <Class java.lang.StringBuffer> 10 dup 11 invokespecial #4 <Method java.lang.StringBuffer()> 14 ldc #5 <String "C2008041422: "> 16 invokevirtual #6 <Method java.lang.StringBuffer append(java.lang.String)> 19 aload_1 20 invokevirtual #6 <Method java.lang.StringBuffer append(java.lang.String)> 23 invokevirtual #7 <Method java.lang.String toString()> 26 invokevirtual #8 <Method void println(java.lang.String)> 29 return
確かに、「Method C2008041422(java.lang.String)」の中で「1 invokespecial #1
対処法の一つ「サブクラスの別のコンストラクタを呼び出す」の
public LazyPerson() { this("なまけもの"); } public LazyPerson(String name) { super(name); }
は、「super(name);」としていないとダメ。ということは、別の解決法「スーパクラスの別のコンストクタを呼び出す」を併用しているような気もする。