加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Scala无法推断Java方法的类型参数

发布时间:2020-12-16 18:37:16 所属栏目:安全 来源:网络整理
导读:我在 Java中有以下复杂的类型层次结构: // the first typeinterface ElementType extends ElementType { Type foo(Type a,Type b);}// the second typeinterface PayloadType extends PayloadType { Type bar(Type[] array);}// some toy implementationfin
我在 Java中有以下复杂的类型层次结构:

// the first type
interface Element<Type extends Element<Type>> {
    Type foo(Type a,Type b);
}

// the second type
interface Payload<Type extends Payload<Type>> {
    Type bar(Type[] array);
}

// some toy implementation
final class SomePayload implements Payload<SomePayload> {
    @Override
    public SomePayload bar(SomePayload[] array) { return array[0]; }
}

// mix of first and second interfaces
interface ComplicatedElement<
              PayloadT extends Payload<PayloadT>,ObjectT extends ComplicatedElement<PayloadT,ObjectT>>
          extends Element<ObjectT> {

    PayloadT getPayload();

    ObjectT add(ObjectT a,ObjectT b);
}

// some toy implementation
final class SomeComplicatedElement 
      implements ComplicatedElement<SomePayload,SomeComplicatedElement> {
    final SomePayload data;

    public SomeComplicatedElement(SomePayload data) {
        this.data = data;
    }

    @Override
    public SomePayload getPayload(){ return data; }

    @Override
    public SomeComplicatedElement foo(SomeComplicatedElement a,SomeComplicatedElement b) {
        return b;
    }

    @Override
    public SomeComplicatedElement add(SomeComplicatedElement a,SomeComplicatedElement b) {
        return a;
    }
}

我有一些处理ComplicatedElements的静态方法:

public static <PayloadT extends Payload<PayloadT>,ObjectT>>
List<ObjectT> method(ObjectT input) {
    return Collections.singletonList(input);
}

现在,从Java我可以调用方法没有这样的问题:

public static void main(String[] args) {
    System.out.println(method(new SomeComplicatedElement(new SomePayload())));
}

但是,当我尝试在Scala中执行相同的操作时:

import FooBarJava.{SomeComplicatedElement,SomePayload,method}

def main(args: Array[String]): Unit = {
  println(method(new SomeComplicatedElement(new SomePayload())))
}

我有这个编译错误:

错误:(10,21)推断类型参数[Nothing,FooJava.SomeComplicatedElement]不符合方法方法的类型参数bounds [PayloadT&lt ;:FooJava.Payload [PayloadT],ObjectT<:FooJava.ComplicatedElement [PayloadT,ObjectT] ]
????println(FooJava.method(new SomeComplicatedElement(new SomePayload())))

我可以通过明确指定类型参数来解决此问题:

println(method[SomePayload,SomeComplicatedElement](new SomeComplicatedElement(new SomePayload())))

但它非常烦人,我想避免这种情况(我想这可能是因为Java编译器可以正常工作).有没有办法这样做?

解决方法

(I guess it is possible since Java compiler just work fine with this)

Scala具有比Java更丰富的类型系统.例如,在Java中,Scala中没有类似于Nothing的类型(即通用子类型).因此,有时类型系统语言中的编译器可能无法推断类型,而在类似情况下,使用较差类型系统的语言编译器可能会这样做.

如果指定类型参数太烦人为什么不创建一些辅助方法呢?

private def methodWithPayload(data: SomePayload): java.util.List[SomeComplicatedElement] =
    method[SomePayload,SomeComplicatedElement](new SomeComplicatedElement(data))

methodWithPayload(new SomePayload)

在Java中有唯一的选项< SomePayload,SomeComplicatedElement>方法(..),在Scala中有两个选项方法[SomePayload,SomeComplicatedElement](..)和方法[Nothing,SomeComplicatedElement](..),两个选项都是有效.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读