2012-07-30 19 views
7

Vorrei implementare un metodo java che utilizza i generici in scala (2.9.2). Ma sto in mancanza ...Scala, impossibile implementare il metodo java generico

metodo di interfaccia Java:

public <T extends Number> void setAttribute(Key<T> key, Number value); 

codice Scala che vogliono attuare tale metodo:

def setAttribute[T <: Number](key: Key[T], value: Number) = { 
    setAttributeLocal(key, value) } 

private def setAttributeLocal[T](key: Key[T], value: T) = { 
    val stringValue = ConvertUtils.convert(value, classOf[String]).asInstanceOf[String] 
    session = session + (key.getValue() -> stringValue) 
} 

chiave assomiglia:

public class Key<T> 

Ma questo non si compila.

[error] found : mypackage.Key[T] 
[error] required: mypackage.Key[java.lang.Number] 
[error] Note: T <: java.lang.Number, but Java-defined class Key is invariant in type T. 
[error] You may wish to investigate a wildcard type such as `_ <: java.lang.Number`. (SLS 3.2.10) 
[error]  setAttributeLocal(key, value) 

Non riesco a capire qual è il problema. Qualche suggerimento/idea?

greez GarfieldKlon

+1

Avremo bisogno di sapere come appare 'Key'. Perché se uso 'chiave di interfaccia pubblica ' il codice sopra compila bene. –

+0

@GarfieldKlon Con quale versione di scala stai lavorando? –

+0

@ 0__ in quale versione viene compilata? –

risposta

4

Sembra che il compilatore è infelice con il tuo invito setAttributeLocal. setAttributeLocal richiede un Key[Number], ma si sta fornendo un Key[_ <: T]. In Java-Land questo significa che stai cercando di passare uno Key<? extends Number> come Key<Number>.

Il suggerimento è di avere setAttributeLocal accettare Key<? extends Number> o Key[_ <: Number], a seconda che sia definito Java o Scala.

+0

@GarfieldKlon Ho dovuto leggerlo alcune volte ... Penso che quello che Ben sta suggerendo è che se ti concentri sulla correzione di "setAttribute", potresti guardare alla cosa sbagliata. L'errore che hai descritto è un problema di tipo con 'setLocalAttribute', non' setAttribute'. Come appare la tua definizione di "setLocalAttribute"? –

+0

@Richard - ok, questo spiega perché non ho potuto riprodurre questo –

+0

Abbiamo finalmente aggiunto questa soluzione: 'def privatoAttributeLocal [T] (chiave: Key [T], valore: Object)' – GarfieldKlon

1

Qui qualcosa sembra un po 'spento.

Hai provato:

def setAttribute[T <: Number](key: Key[T], value: T) = 
    setAttributeLocal(key, value) 

Sembra strano/cattivo per preservare il tipo T per la chiave, ma non usarla sul valore. La mia ipotesi è che qui trovi un errore invariante. Stai provando ad assegnare il valore di tipo Number a una chiave di tipo T e il compilatore non è sicuro se non può passare Number per T (mentre sa che può passare T per Number).

Possiamo vedere più codice?

+0

Questa non è un'opzione, perché non è un override. – GarfieldKlon

+0

Esistono limitazioni nelle interfacce di tipo Java e Scala. Quello che stai facendo in Java è di tipo non corretto, e quindi Scala lo esclude. Se si desidera continuare a utilizzare quel tipo di procedura guidata, è necessario attenersi al sistema di tipi Java, mi dispiace. – jsuereth

1

Come @jsuereth già indicate, v'è una discrepanza tra le firme di setAttribute e setAttributeLocal, cioè, che il primo accetta un Key[T <: Number] ma fissa il valore che va con la chiave per essere esattamente un Number, mentre la seconda è più flessibile e consente a chiave e valore di essere T <: Number. Questo sembra piuttosto strano e potresti voler riconsiderare questa decisione. Porta anche al problema spiegato da @Ben Schulz.

In ogni caso, il compilatore (2.9.1) è felice con la seguente configurazione:

MyI.java:

public interface MyI { 
    public <T extends Number> void setAttribute(Key<T> key, Number value); 
} 

Key.java:

public interface Key<T> { 
} 

Test.scala:

object Test extends App { 
    def setAttribute[T <: Number](key: Key[T], value: Number) = { 
    setAttributeLocal(key, value) } 

    private def setAttributeLocal[T](key: Key[T], value: Number) = { 
    /* Notice that value is now also of type Number. */ 
    } 
} 
Problemi correlati