2011年9月22日木曜日

Javaのクラスに同名、同引数のメソッドが定義される件

javaの仕様?と思われますが、ある特定の条件下でリフレクションを使用した場合、困ったことになります。

例えば、このようなクラスを定義します。

scala

trait FirstDef[T]{
def id : T
}

class Conc extends FirstDef[Long]{
def id = 23L
}


java

interfaceFirstDef{
public T id();
}

class Conc implements FirstDef{
public Long id() = 23L
}

そして、ConcクラスをReflectionにかけると・・・


> classOf[Conc].getMethods(println(_))

public long Conc.id()
public java.lang.Object Conc.id()
public final native void java.lang.Object.wait(long) th
public final void java.lang.Object.wait() throws java.l
public final void java.lang.Object.wait(long,int) throw
public boolean java.lang.Object.equals(java.lang.Object
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.ge
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()



なんと、引数なしのid()メソッドが2つ定義されてしまいます!!!
しかし、戻り値はlongとjava.lang.Object。
Reflectionをがりがり使うライブラリを使用している場合、高確率でバグが出ちゃいます。

これは、継承しているTrait(Interface)の型テンプレートを実現するためと思われ、回避不可能です。Reflectionを使用するライブラリを作る場合はこのようなことがあるということに気をつけましょう。

0 件のコメント:

コメントを投稿