2016-10-06 10 views
5

ジェネリック型を扱っているため、特定のケースクラスを使用できません。次に、汎用オブジェクトをシリアライズしてデシリアライズする汎用ユーティリティを作成しました。json4sジェネリック型をシリアライズしてデシリアライズ

import org.json4s 
import org.json4s.Formats._ 
import org.json4s.native.JsonMethods._ 

object JsonHelper { 
    def json2Object[O](input: String) : O = { 
    parse(json4s.string2JsonInput(input)).asInstanceOf[O] 
    } 
    def object2Json[O](input: O) : String = { 
    write(input).toString 
    } 
} 

コンパイラはエラーをスロー:

No JSON serializer found for type O. Try to implement an implicit Writer or JsonFormat for this type. write(input).toString

これは、実行時にスローされる必要がありますが、それはコンパイル時にスローされますなぜですか?

+0

あなたの心の中でどのようなことが起こりますか? 「O」が何かになる可能性がある場合、json4はどのようにすべての場合に何をすべきかを知ることになるでしょうか? WriterやJsonFormatがOに対して定義されている限り、あなたの 'write(input) 'のことは動作します。コンパイル時にこれは見つけられません。 – mfirry

+1

@mfirryしたがって、jacksonがJavaオブジェクトで動作する方法は? 反射権を使用していますか?なぜScalaと異なるのですか? –

答えて

7

、あなたは "尋ねましたそれで、ジャックソンがJavaオブジェクトで動作するのはどういうふうに反映されているのでしょうか?それはなぜScalaとは違うのですか?」という質問があります。

インポートしたjson4s「ネイティブ」シリアライザは、コンパイル時リフレクションを使用してWriterを作成します。

ジャクソンは同じことを行うために実行時リフレクションを使用します。

コンパイル時の方が効率的です。ランタイムバージョンはより柔軟です。

コンパイル時のバージョンを使用するには、コンパイラに、シリアル化されるオブジェクトの宣言された型に基づいて正しいWriterを選択するのに十分な情報を持たせる必要があります。これは、あなたが提案するような非常に一般的なライターメソッドを除外します。そのバージョンのコードを修正する方法については、@ TimPの回答を参照してください。

ランタイムバージョンを使用するには、org.json4s.jackson.JsonMethods._パッケージでJacksonを使用できます。 https://github.com/json4s/json4s#jackson

1

この例では、Scalaは別のjvm言語と同様に、コンパイル時にtype erasingメカニズムを持っています(コンパイル時のエラーメッセージにはジェネリックに関するメッセージが含まれていない可能性があります)。

(implicit tag: ClassTag[T]) 

it's一般的な、しかし、ジャクソンとして、あなたの例のように:両方のメソッドのシグネチャにこのフラグメントを追加します。 HTH

5

投稿したコンパイラエラーはthis location in the json4s codeです。呼び出す関数writeは暗黙のJSON Writerを取ります。これはメソッドが任意の型を取る方法です。暗黙の引数は明示的なものであると同じようにコンパイルされているので、それはコンパイル時にキャッチされます - あなたが持っていたかのようにです:

def f(a: Int, b: Int) = a + b 
f(5) // passed the wrong number of arguments 

私はトラブルは正確に見て、あなたがここに呼んでいるそのwrite方法のビットを持っています - - json4sライブラリはかなり大きく、物事が過負荷になっています。宣言したwriteメソッドを貼り付けることはできますか?それはほぼ確実にこのようなシグネチャがあります。

def write[T](value: T)(implicit writer: Writer[T]): JValue 

それは上記のように見える場合は、ようにあなたの方法で暗黙の作家のパラメータを含めてみてください:上記のコメントで

object JsonHelper { 
    def json2Object[O](input: String)(implicit reader: Reader[O]) : O = { 
    parse(json4s.string2JsonInput(input)).asInstanceOf[O] 
    } 
    def object2Json[O](input: O)(implicit writer: Writer[O]) : String = { 
    write(input).toString 
    } 
} 
関連する問題