著作一覧 |
public String add(CharSequence a, CharSequence b) { StringBuffer s = new StringBuffer(a.toString()); s.append(b); return new String(s); }
というメソッドが(あるわけないが、例として)あるとする。
そのメソッドを呼び出すと、MethodNotFoundExceptionになるんですが? という問い合わせが来る。
そんな馬鹿な、と思う。で、環境を聞いてみるとJ2RE 1.4だと言う。それならOKなはずだが。
しかし、なんでスタックトレースそのものを出さないのかね。でも例外のメッセージは来た。見た。
Exception in thread "main" java.lang.NoSuchMethodError: java.lang.StringBuffer.(Ljava/lang/CharSequence;)V
って言うか、J2SE 1.4のStringBuffer#appendにはそんなメソッドはないのだが。
どうもアングラで入手したソースを1.5でビルドしたんじゃないか? というかほかに考えられないのだが。
javac -target 1.4 -source 1.4 Buf.java として、 javap -classpath . -c Buf すると、 public java.lang.String add(java.lang.CharSequence, java.lang.CharSequence); Code: 0: new #2; //class java/lang/StringBuffer 3: dup 4: aload_1 5: invokevirtual #3; //Method java/lang/Object.toString:()Ljava/lang/String; 8: invokespecial #4; //Method java/lang/StringBuffer."":(Ljava/lang/String;)V 11: astore_3 12: aload_3 13: aload_2 14: invokevirtual #5; //Method java/lang/StringBuffer.append:(Ljava/lang/CharSequence;)Ljava/lang/StringBuffer; となる。
1.4でコンパイルすると、当たり前だがJ2SE1.4にはStringBuffer#append(CharSequence)なんてメソッドは存在しないから
Code: 0: new #2; //class StringBuffer 3: dup 4: aload_1 5: invokevirtual #3; //Method java/lang/Object.toString:()Ljava/lang/String; 8: invokespecial #4; //Method java/lang/StringBuffer."":(Ljava/lang/String;)V 11: astore_3 12: aload_3 13: aload_2 14: invokevirtual #5; //Method java/lang/StringBuffer.append:(Ljava/lang/Object;)Ljava/lang/StringBuffer;
となる。
-targetでどうにかなるのは、言語仕様に関するところだと言うことが結論かな。
本当の結論は、1.4をターゲットにした開発をする場合、開発環境のJ2SEも1.4にしておけ、ということだ。わかってやってるなら良いのだが、わかってなくて人に問い合わせるってとこがあまりにも困ったちゃんである。っていうか、ソース共有は良いのだが、jarは配布したものを使ってて欲しいな。デバッグオプションはフルに設定してるんだから。
ジェズイットを見習え |