gpt4 book ai didi

scala - 在 Scala 中用 arg Class 覆盖 Java 方法

转载 作者:行者123 更新时间:2023-12-02 01:18:05 25 4
gpt4 key购买 nike

我正在尝试从无法更改的外部库中继承一个类 (Y)。它有这样的方法:

protected Object doSomething(Class<?> clazz)

现在在我的 Scala 类 (X) 中,我正在扩展此类并尝试覆盖该方法。

override protected def doSomething(clazz: Class[_ <: Object]): AnyRef

然而,这会导致“Method doSomething overrides nothing”。将代码更改为:

override protected def doSomething(clazz: Class[_]): AnyRef

停止此错误,但现在编译类时会导致以下错误:

class X needs to be abstract, since method doSomething in class Y of type (x$1: Class[_ <: Object])Object is not defined 
(Note that Class[_ <: T] does not match Class[_]: their type parameters differ)

有什么办法可以实现吗? Scala 版本:2.12.1,Java 版本 8。

最佳答案

在问题中你没有提到 Object doSomething(Class<?> clazz)方法是 abstract T doSomething(Class<? extends T> clazz) 的实现抽象泛型类的方法。

所以实际上您有以下 Java 类(为简洁起见,我将 doSomething 重命名为 test):

public abstract class AbstractJava<T> {
protected abstract T test(Class<? extends T> c);
}

public class ConcreteJava extends AbstractJava<Object> {
@Override
protected Object test(Class<?> c) {
return null;
}
}

并且您正在尝试实现以下 Scala 类:

class ConcreteScala extends ConcreteJava {
override protected def test(c: Class[_]) = super.test(c)
}

但是编译失败了,因为当你试图覆盖 test() 时Scala对待ConcreteJava.test()AbstractJava.test()方法就像它们具有不同的签名一样。

我找到了以下解决方法。

通过覆盖 test() 创建额外的 Java 类将其“重命名”为 renameTest()并且还提供调用 super ConcreteJava.test() 的能力通过concreteTest()方法。

public abstract class RenameJava extends ConcreteJava {
public Object concreteTest(Class<?> c) {
return super.test(c);
}

abstract protected Object renameTest(Class<?> c);

@Override
protected Object test(Class<?> c) {
return renameTest(c);
}
}

现在 ConcreteScala您可以覆盖的类 renameTest()你仍然可以调用 super ConcreteJava.test()使用 concreteTest() 的方法方法。

class ConcreteScala extends RenameJava {
override protected def renameTest(c: Class[_]) = {
// custom logic
concreteTest(c)
}
}

在您特定的“Spring”案例中,它是通过以下方式实现的。

重命名GsonHttpMessageConverter.java

import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.json.GsonHttpMessageConverter;

import java.io.IOException;

public abstract class RenameGsonHttpMessageConverter extends GsonHttpMessageConverter {

protected Object superReadInternal(Class<?> clazz, HttpInputMessage inputMessage) throws
IOException, HttpMessageNotReadableException {
return super.readInternal(clazz, inputMessage);
}

abstract protected Object renameReadInternal(Class<?> clazz, HttpInputMessage inputMessage) throws
IOException, HttpMessageNotReadableException;

@Override
protected Object readInternal(Class<?> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
return renameReadInternal(clazz, inputMessage);
}
}

CustomGsonHttpMessageConverter.scala

import org.springframework.http.HttpInputMessage

class CustomGsonHttpMessageConverter extends RenameGsonHttpMessageConverter {
override protected def renameReadInternal(clazz: Class[_], inputMessage: HttpInputMessage) = {
// custom logic
// or you may want to call
superReadInternal(clazz, inputMessage)
}
}

我还做了一个错误报告 SI-10155 .

关于scala - 在 Scala 中用 arg Class<?> 覆盖 Java 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41649352/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com