2014-04-01 13 views
6

Say I zdefiniować następujący interfejs Java:przesłonić metodę Javy, która spodziewa się podwójna tablica

public interface A 
{ 
    public Double[] x(); 
} 

a następnie spróbuj wdrożyć go w Scala następująco:

class B extends A { 
    val v: Array[Double] = Array(2.3, 6.7) 
    override def x() = v 
} 

Kompilator daje mi następujący błąd:

type mismatch; 
[error] found : Array[scala.Double] 
[error] required: Array[java.lang.Double] 
[error]  override def x() = v 

Czy ktoś może mi polecić sposób automatycznej konwersji tej tablicy?

Dzięki Des

+0

Czy tablica jest wystarczająco duża i dostępna na tyle, aby wydajność mogła być problemem? Również twój komentarz poniżej jest ważny - musisz "używać" "czystej Scali". –

Odpowiedz

6

Nie można przekonwertować go automatycznie. Problem polega na tym, że Double w Javie oznacza klasę java.lang.Double (podczas gdy w Scali oznacza to scala.Double, która jest w większości taka sama jak double w Javie), a więc nadrzędna metoda ma, aby zwrócić Array[java.lang.Double]. Jeśli masz Array[Double], można przekonwertować go za pomocą map:

val v: Array[Double] = ... 
val v1 = v.map(java.lang.Double.valueOf(_)) // valueOf converts Double into java.lang.Double 

Ty mógłby dokonać tej konwersji niejawny:

implicit def wrapDoubleArray(arr: Array[Double]): Array[java.lang.Double] = 
    arr.map(java.lang.Double.valueOf(_)) 

ale to jest zły pomysł, w większości przypadków.

+0

Dlaczego niejawna konwersja jest zazwyczaj złym pomysłem? – user79074

+0

1. Może zaistnieć konieczność dodania podobnych konwersji dla tablic innych typów pierwotnego opakowania (np. 'Java.lang.Integer',' java.lang.Long', itp.), Dla typów innych niż 'Tablica' (' Lista', 'Seq',' Map' i tak dalej). –

+0

2. Ta konwersja nie jest trywialna (musi faktycznie utworzyć nową tablicę i wypełnić ją), co powoduje ukrywanie kosztów. –

1

to pomoże?

class B extends A { 
    val v: Array[java.lang.Double] = Array(2.3D, 6.7D) 
    override def x() = v 
} 
+0

Nie bój się, v powinien być czystym typem scala. – user79074

2

Jeśli typ v musi być Array[scala.Double], to może należy rozważyć wykonanie konwersji siebie w zastąpiona metoda:

class B extends A { 
    val v: Array[Double] = Array(2.3, 6.7) 

    override def x(): Array[java.lang.Double] = { 
    v map { java.lang.Double.valueOf(_) } 
    } 
} 
Powiązane problemy