说我有这个自我约束的java类:

public class SelfBounded<SELF extends SelfBounded<SELF>> {
    public String testField = "TEST";

    public SelfBounded() {

    }

    public SELF testMethod() {
        return (SELF) this;
    }
}

在Java中,我们可以这样编写:
public class SelfBoundedMainJava {
    public static void main(String[] args) {
        SelfBounded selfBounded = new SelfBounded();
        System.out.println(selfBounded.testField);
        System.out.println(selfBounded.testMethod().testField);
    }
}

这段代码给了我2x的“测试”,正如我期望的那样。

但是我正在努力在scala中写同样的东西:

如果我不传递类型,它将成为SelfBounded [Nothing]。但是尝试使用“:: SelfBounded [SelfBounded]”中的SelfBounded类型,由于具有递归特性,这给我带来了麻烦,并且编译器告诉我每个“SelfBounded”都需要一个类型参数。
object SelfBoundedMainScala extends App {
  // here the type of selfBounded1 is SelfBounded[Nothing]
  val selfBounded1 = new SelfBounded()
  println(selfBounded1.testField)
  // does not work since testMethod() returns a Nothing
  //println(selfBounded1.testMethod().testField)

  // trying to set the type of the selfBounded variable gives me issues because of the recursive type
  // does not compile 'class SelfBounded takes type parameters'
  // val selfBounded2: SelfBounded[SelfBounded] = new SelfBounded()
  // same issue
  // val selfBounded3 = new SelfBounded[SelfBounded]()
}

在不更改SelfBounded类定义的情况下,有什么方法可以在Scala中完成Java主类?

注意:这是在Scala中尝试使用testcontainers-java时的简化示例。

最佳答案

当您用Java编写SelfBounded selfBounded = new SelfBounded()时,您使用的是raw types,其存在仅是为了与前泛型代码兼容。不要那样做正确的方法是扩展SelfBounded:

class SelfBounded1 extends SelfBounded<SelfBounded1> {}

public class SelfBoundedMainJava {
    public static void main(String[] args) {
        // or SelfBounded<?> selfBounded
        SelfBounded1 selfBounded = new SelfBounded1();
        System.out.println(selfBounded.testField);
        System.out.println(selfBounded.testMethod().testField);
    }
}

在Scala中也是如此,不同之处在于它不支持原始类型,因为自开始以来就具有类型参数:
object SelfBoundedMainScala extends App {
  class SelfBounded1 extends SelfBounded[SelfBounded1]

  val selfBounded1 = new SelfBounded1()
  println(selfBounded1.testField)
  println(selfBounded1.testMethod().testField)
}

09-04 00:07