こんな感じのseald classを作る
sealed class SampleEvent(open val name: String) class SampleEventA( override val name: String ): SampleEvent(name)
こんな感じでJson作る
Gson().toJson(SampleEventA("aaaaa"))
気持ちとしては以下のようなjsonが出て欲しい
{"name":"aaaa"}
でもエラーが出る
SampleEventA declares multiple JSON fields named name
ほほう
Tools > Kotlin > Show Kotlin Bytecode
でBytecodeからのJavaにDecompileしてどんな感じか見る。
public final class SampleEventA extends SampleEvent { @NotNull private final String name; @NotNull public String getName() { return this.name; } public SampleEventA(@NotNull String name) { Intrinsics.checkParameterIsNotNull(name, "name"); super(name, (DefaultConstructorMarker)null); this.name = name; } } public abstract class SampleEvent { @NotNull private final String name; @NotNull public String getName() { return this.name; } private SampleEvent(String name) { this.name = name; } // $FF: synthetic method public SampleEvent(@NotNull String name, DefaultConstructorMarker $constructor_marker) { this(name); } }
abstract classと継承したclassの両方でnameが作られていてそれが原因でエラーが出てるようだ。
javaでabstractを使った時にちゃんと動かすならこんな感じで書けばよさそうだった
abstract class JavaSampleEvent { protected final String name; public JavaSampleEvent(String name) { this.name = name; } } class JavaSampleA extends JavaSampleEvent { public JavaSampleA(String name) { super(name); } }
String json = new Gson().toJson(new JavaSampleA("aaaa"));
最後に
結局、Seald Classを使わずにInterfaceを使って対応したのだけど、こういう場合はどうやってやるのがよかったのだろうか。。。??
追記
Twitterでいい感じに出来る方法を教えて頂きました!!
sealed class SampleEvent { abstract val name: String } class SampleEventA( override val name: String ) : SampleEvent()
abstractでプロパティを宣言すれば大丈夫だった。 sealed class使う時にいつもopen使ってやってたけど、こっちの方がよさそうだなー