3

У меня есть библиотека Java с некоторыми родовыми контейнерами:Как вызвать функцию группового символа Java от Скале

public interface IColumnTable<T extends IColumn<?, ?>> 
{ 
} 
public interface IColumn<D extends IColumnValues<?>, M extends IMetaData> 
{ 
} 
public interface IColumnValues<E> 
{ 
} 
public interface IMetaData 
{ 
} 

и фабричный метод, чтобы получить конкретные примеры их

public interface StorageFactory 
{ 
IColumnTable<? extends IColumn<? extends IColumnValues<?>, ? extends IMetaData>> read(String tableName) throws IOException; 
} 

И у меня тоже есть полезный метод, который вводит мои подстановочные таблицы (путем литья и преобразования значений)

public class TableConverterUtil 
{ 
public static <T, V> IColumnTable<IColumn<IColumnValues<T>, IMetaData>> getPureTypedTable(
     IColumnTable<? extends IColumn<? extends IColumnValues<V>, ? extends IMetaData>> tableRaw, 
     Class<T> type, 
     Optional<Function<V, Optional<T>>> converter 
    ) 
} 

(Обратите внимание на использование V вместо? в качестве параметра для IColumnValues)

В Java я могу назвать следующие, чтобы получить таблицу со значениями Double:

try { 
      IColumnTable<IColumn<IColumnValuesExact<Double>, IMetaData>> myDoubleTable = TableConverterUtil.getPureTypedTable(
       StorageManagerUtil.getDefault().get("default").read("myTableName"), 
       Double.class, 
       Optional.empty() 
      ); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (StorageManagerInstantiationException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

Однако в Scala не кажется, чтобы быть в состоянии получить тот же самый вызов работа:

TableConverterUtil.getPureTypedTable(
    StorageManagerUtil.getDefault.get("default").read("myTableName"), 
    classOf[Double], 
    Optional.empty() 
) 

Результаты в:

[file and line number]: no type parameters for method emp 
ty:()java.util.Optional[T] exist so that it can be applied to arguments() 
[error] --- because --- 
[error] undetermined type 
[error]  Optional.empty() 
[error]    ^
[error] [file and line number]: type mismatch; 
[error] found : java.util.Optional[T] 
[error] required: java.util.Optional[java.util.function.Function[?,java.util.Op 
tional[?]]] 
[error]  Optional.empty() 
[error] 

       ^

Я также пробовал с нулем вместо Op tional.empty(), что приводит к:

[error] [file & line no]: no type parameters for method get 
PureTypedTable: (x$1: com.wwa.data.interfaces.IColumnTable[_ <: com.wwa.data.int 
erfaces.IColumn[_ <: com.wwa.data.interfaces.IColumnValues[V], _ <: com.wwa.data 
.interfaces.IMetaData]], x$2: Class[T], x$3: java.util.Optional[java.util.functi 
on.Function[V,java.util.Optional[T]]])com.wwa.data.interfaces.IColumnTable[com.w 
wa.data.interfaces.IColumn[com.wwa.data.interfaces.IColumnValuesExact[T],com.wwa 
.data.interfaces.IMetaData]] exist so that it can be applied to arguments (com.w 
wa.data.interfaces.IColumnTable[?0], Class[Double], Null) 
[error] --- because --- 
[error] argument expression's type is not compatible with formal parameter type; 

[error] found : com.wwa.data.interfaces.IColumnTable[?0(in method doWork)] wh 
ere type ?0(in method doWork) <: com.wwa.data.interfaces.IColumn[_ <: com.wwa.da 
ta.interfaces.IColumnValues[_], _ <: com.wwa.data.interfaces.IMetaData] 
[error] required: com.wwa.data.interfaces.IColumnTable[_ <: com.wwa.data.interf 
aces.IColumn[_ <: com.wwa.data.interfaces.IColumnValues[?V], _ <: com.wwa.data.i 
nterfaces.IMetaData]] 
[error]  TableConverterUtil.getPureTypedTable(
[error]      ^
[error] [file & line No.]: type mismatch; 
[error] found : com.wwa.data.interfaces.IColumnTable[?0(in method doWork)] wh 
ere type ?0(in method doWork) <: com.wwa.data.interfaces.IColumn[_ <: com.wwa.da 
ta.interfaces.IColumnValues[_], _ <: com.wwa.data.interfaces.IMetaData] 
[error] required: com.wwa.data.interfaces.IColumnTable[_ <: com.wwa.data.interf 
aces.IColumn[_ <: com.wwa.data.interfaces.IColumnValues[V], _ <: com.wwa.data.in 
terfaces.IMetaData]] 
[error]  StorageManagerUtil.getDefault.get("default").read("myTableName"), 
[error]  

               ^

Я также попробовал вспомогательный метод в ловушку подстановочные дано IColumnValues ​​так, что я могу на самом деле передать функцию в Но не повезло, он не кажется, что всякий раз, когда я пытаюсь. и привязать один из внутренних параметров к именованному типу, компилятор выбрасывает подгонку.

Я могу сменить библиотеку Java, но думаю, что мне что-то не хватает, поскольку Scala и Java должны быть полностью совместимы.

Есть ли способ вызвать getPureTypedTable из scala без изменения java? (с функцией преобразователя не равно нулю или пустой опциональный)

PS: Извините за долго наматывается размещать его в пятницу вечером, и я смотрел на это на некоторое время теперь

+3

Скомпилирует ли он, если вы явно указываете тип необязательного - e. г. 'Optional.empty [java.util.function.Function [_, _]]()'? –

+0

Вывод типа Scala может иногда путаться; Я подозреваю в этом случае параметр типа 'V', поскольку он не используется в любом месте в вызове. В качестве первого шага попробуйте передать явные параметры типа, например. 'getPureTypedTable [Double, Double] (...)'. – lmm

+0

Нет, он не скомпилирован с подстановочными знаками. –

ответ

0

Кажется, я нашел ответ на этот группа нить Скала https://groups.google.com/forum/#!topic/scala-user/JlCsy48poIU

Она включает в себя сопоставление с образцом назвать тип, но и дает компилятору предупреждение о непроверенных типов, которые я думаю, что это безопасно игнорировать ...

def callWildcardTableFunction(table: IColumnTable[_ <: IColumn[_ <: IColumnValues[_], _ <: IMetaData]]) 
    : IColumnTable[IColumn[IColumnValues[Double], IMetaData]] = table match 
    { 
    case boundTable: IColumnTable[IColumn[IColumnValues[valueType], m]] @unchecked => 
     TableConverterUtil.getPureTypedTable[Double, valueType](boundTable, classOf[Double], null) 
    } 

Если у кого есть лучший способ/Это на самом деле небезопасно, скажите!