2012-11-26 118 views
0

我想在scala上使用java的反射API。我有一個使用ClassLoader從字節碼中加載的KDTree類。下面是它的方法:scala中的Java類反射

public class KDTree 
{ 
public KDTree(int k) 
public void insert(double[] key, Object value) throws Exception 
public Object[] range(double[] lowk, double[] uppk) throws Exception 
} 

,這裏是我的包裝的Scala類:

class KDTree(dimentions: Int) 
    //wrapper! 
    { 
    private val kd= Loader.loadClass("KDTree") 
    private val constructor= kd.getConstructor(java.lang.Class.forName("java.lang.Integer")) 
    val wrapped= constructor.newInstance("1") 
    def insert(key:Array[Double], element:Object)= 
     kd.getDeclaredMethod("insert", classOf[Array[Double]]) 
      .invoke(key, element) 
    def range(lowkey:Array[Double], highkey:Array[Double])= 
     kd.getDeclaredMethod("range", classOf[Array[Double]]) 
      .invoke(lowkey, highkey) 
    } 

當我嘗試初始化我得到一個錯誤:

java.lang.NoSuchMethodException: KDTree.<init>(java.lang.Integer) 

然而,構造函數的唯一參數的確一個整數!

而且,我不能簡單地做java.lang.Integer.class,因爲斯卡拉抱怨的語法:error: identifier expected but 'class' found.

沒有人有什麼祕訣嗎?

編輯 這裏是我完成的代碼,如果有一個人使用它:

class KDTreeWrapper[T](dimentions: Int) 
{ 
private val kd= Loader.loadClass("KDTree") 
private val constructor= kd.getConstructor(classOf[Int]) 
private val wrapped= constructor.newInstance(dimentions:java.lang.Integer) 
    .asInstanceOf[Object] 
private val insert_method= kd. 
    getMethod("insert", classOf[Array[Double]], classOf[Object]) 
private val range_method= 
    kd.getMethod("range", classOf[Array[Double]], classOf[Array[Double]]) 
def insert(key:Iterable[Double], element:T)= 
    insert_method.invoke(wrapped, key.toArray, element. 
     asInstanceOf[Object]) 
def range(lowkey:Iterable[Double], highkey:Iterable[Double]):Array[T]= 
    range_method.invoke(wrapped, lowkey.toArray, highkey.toArray). 
     asInstanceOf[Array[T]] 
} 
+0

究竟爲什麼被反射在這裏需要的? – Arjan

+0

@Arjan因爲[我需要一個帶有我所有代碼的單個scala文件](http://stackoverflow.com/questions/13554617),KDTree是我在前面提到的Java庫 –

回答

3

你的問題是,你嘗試加載一個構造函數的類型參數java.lang.Integer。試用int.class

此外,它寫的更短,kd.getConstructor(int.class)

+0

中的一部分,在scala中有任何東西。類'抱怨 –

+2

使用'classOf [Integer]'或'classOf [int]'ans描述[here](http://stackoverflow.com/questions/1135248/scala-equivalent-of-java-java-lang-classt-目的)。 –

+0

啊,明白了!謝謝! –

0

我覺得我的例子是簡單了很多,但可能是因爲我寫的:

class Config { 
    val c = "some config" 
} 

class Moo(c: Config) { 
    val x = "yow!" 
} 

class Loo(c: Config) extends Moo(c) { 
    override val x = c.c + " yodel!" 
} 

object CallMe { 
    def main(args: Array[String]) { 
    val cn = new Config 

    // val m: Moo = new Loo(cn) 

    val c = Class.forName("Loo") 
    val ars = c.getConstructor(classOf[Config]) 
    val m: Moo = ars.newInstance(cn).asInstanceOf[Moo] 

    println(m.x) 
    } 
} 

打印出

some config yodel!