如何在Scala中使用Java自绑定类

3

假设我有这个自限定的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);
    }
}

这段代码按照我的期望输出了2个"TEST"。

但是我在尝试用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。
1个回答

2

当你在Java中写SelfBounded selfBounded = new SelfBounded()时,你使用了原始类型,这种类型只是为了与泛型之前的代码兼容而存在的。不要这样做。正确的方式是继承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)
}

谢谢!这是一个好的解决方案。但我想知道为什么在testcontainers-java示例中他们会这样使用它?https://github.com/testcontainers/testcontainers-java-examples/blob/master/redis-backed-cache/src/test/java/RedisBackedCacheTest.java - R Pieters
自限定类是GenericContainer(https://github.com/testcontainers/testcontainers-java/blob/master/core/src/main/java/org/testcontainers/containers/GenericContainer.java). - R Pieters
这可能是使用原始类型的合理用途(我见过的第一个)。在Scala中,您可以使用this.type实现相同的结果,但Java没有相应的功能。 - Alexey Romanov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接