2017-01-14 2 views
3

変更できないクラス(Y)を外部ライブラリからサブクラス化しようとしています。argでJavaメソッドをオーバーライドするScalaの<?>クラス

protected Object doSomething(Class<?> clazz) 

私のScalaクラス(X)では、このクラスを拡張してメソッドをオーバーライドしようとしています。

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

しかし、これは「方法doSomethingは何も無効にしません」という結果に終ります。このエラーは

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.

+1

jdkとscalaのバージョンを教えてください – Odomontois

+0

「def def doSomething [T](clazz:Class [T]):AnyRef'をオーバーライドしようとしましたか? – marstran

+1

'def override doSomething(clazz:Class [_]):AnyRef = ???'はScala 2.11.8とJDK 8u91 –

答えて

1

質問では、Object doSomething(Class<?> clazz)メソッドは抽象ジェネリッククラスのabstract T doSomething(Class<? extends T> clazz)メソッドの実装であるとは言及していませんでした。

だから、実際には、次のしているJavaクラスは、(私は簡潔にするためtestdoSomethingに改名):

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()のメソッドを異なるシグネチャを持つものとして扱います。

次の回避策が見つかりました。

renameTest()にそれを「名前の変更」ともconcreteTest()方法を通じてスーパーConcreteJava.test()を呼び出す機能を提供test()をオーバーライドしていることを、追加のJavaクラスを作成します。

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()を上書きすることができますし、あなたはまだ concreteTest()法を用いた超 ConcreteJava.test()メソッドを呼び出すことができるしています。

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

具体的な「春」のケースでは、次のように実装されています。

RenameGsonHttpMessageConverter.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を作りました。

関連する問題