简体   繁体   English

如何从scala调用通配符java函数

[英]How to call wildcard java function from scala

I have a java library with some generic containers: 我有一个带有一些通用容器的java库:

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

and a factory method to get concrete instances of them 和一个工厂方法来获取它们的具体实例

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

And I also have a utility method that types my wildcard tables (through casting and converting of values) 我还有一个实用工具方法,可以输入我的通配符表(通过转换和转换值)

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
    ) 
}

(Note the use of V instead of ? as the parameter for IColumnValues) (注意使用V代替?作为IColumnValues的参数)

In java I can call the following to get a table with values of Double: 在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();
        }

However in Scala I don't seem to be able to get the same call to work: 但是在Scala中我似乎无法获得相同的工作调用:

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

Results in: 结果是:

[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] 

                ^

I have also tried it with null instead of Optional.empty() which results in: 我也尝试使用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]    

                                                ^

I have also tried an auxiliary method to trap the wildcard given to IColumnValues so that I can actually pass a function in. But no luck, it seems that whenever I try and bind one of the inner _ to a named type parameters the compiler throws a fit. 我还尝试了一种辅助方法来捕获给予IColumnValues的通配符,以便我可以实际传递一个函数。但是没有运气,似乎每当我尝试将内部_之一绑定到命名类型参数时,编译器抛出一个适合。

I can at a stretch change the Java library but think I must be missing something as Scala and Java should be totally interoperable. 我可以一直改变Java库,但认为我必须遗漏一些东西,因为Scala和Java应该是完全可互操作的。

Is there a way to call the getPureTypedTable from scala without changing the java? 有没有办法从scala调用getPureTypedTable而不更改java? (with a converter function not null or empty optional) (转换器函数不为null或为空可选)

PS: Sorry for long winded post its late on Friday and I've been staring at this for a while now PS:很抱歉在周五晚些时候发了很长时间的帖子,我已经盯着这一段了一段时间了

Think I found the answer in this scala group thread https://groups.google.com/forum/#!topic/scala-user/JlCsy48poIU 想想我在这个scala组线程中找到了答案https://groups.google.com/forum/#!topic/scala-user/JlCsy48poIU

It involves pattern matching to name the type but also gives a compiler warning about unchecked types which I think is safe to ignore... 它涉及模式匹配以命名类型,但也提供编译器警告有关未经检查的类型,我认为可以安全忽略...

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)
  }

If anyone has a better way / this is actually not safe please say! 如果有人有更好的方法/这实际上不安全请说!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM