[英]How to call wildcard java function from scala
我有一個帶有一些通用容器的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]
^
我也嘗試使用null而不是Optional.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應該是完全可互操作的。
有沒有辦法從scala調用getPureTypedTable而不更改java? (轉換器函數不為null或為空可選)
PS:很抱歉在周五晚些時候發了很長時間的帖子,我已經盯着這一段了一段時間了
想想我在這個scala組線程中找到了答案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)
}
如果有人有更好的方法/這實際上不安全請說!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.