如何使用gson.fromJson()强制Kotlin调用我的类初始化程序?

时间:2019-02-16 19:58:04

标签: java kotlin initialization gson

在Kotlin项目中,我让Gson将来自JSON源的数据注入到我制作的某些类中。数据注入,但是从未调用类init {...}。

import com.google.gson.GsonBuilder

fun main(args: Array<String>) {
    val myClass1 = MyClass("Hello!")
    // should have printed "Hello!"

    val jsonOfMyClass = "{myData:\"Hey!\"}"
    val gson = GsonBuilder().create()
    val myClass2 = gson.fromJson(jsonOfMyClass, MyClass::class.java)
    // should have printed "Hey!" but it doesn't init?

    myClass2.printData()
    // so I have to manually call my own init
}

class MyClass constructor(private val myData: String) {
    init {
        printData()
    }

    fun printData() {
        println("My Data: $myData")
    }
}

无需手动调用的结果:

<!-- language: lang-none -->

My Data: Hello!

手动调用的结果:

<!-- language: lang-none -->

My Data: Hello!
My Data: Hey!

不应该这样称呼它吗?正在实例化我的课程,对吧?

如果没有,是否有办法强制初始化{...}?还是我必须调用公共方法(如我在示例中所做的那样?)

1 个答案:

答案 0 :(得分:0)

您可以使用InstanceCreator进行此操作。我的示例是在Java中编写的(情况稍有不同,以展示可能性),但是您可以将相关信息纳入Kotlin项目中。

假设您有一个类似的课程:

@Getter
public class MyClass {

    private String name; 
    private String myData; 

    public void init(String myData) {
        this.myData = myData;
    }        

}

然后您将拥有 test.json ,例如:

{
    "name": "My Name",
    "myData": "My Data"
}

要将 myData 反序列化为其他值或在反序列化阶段进行任何其他初始化,您可以注册InstanceCreator,如下所示:

public class MyInstanceCreator implements InstanceCreator<MyClass>{

    @Override
    public MyClass createInstance(Type type) {
        MyClass myClass = new MyClass();
        myClass.init("Instance creator put this data");
        return myClass;
    }

}

反序列化,如:

@Test
public void test() {
    Gson gson = new GsonBuilder().setPrettyPrinting()
        .registerTypeAdapter(MyClass.class, new MyInstanceCreator())
        .create();        
    MyClass myClass = gson.fromJson(
        new InputStreamReader(getClass()
            .getResourceAsStream("test.json")),
        MyClass.class);
   log.info("\n{}", gson.toJson(myClass)); 
}

将导致类似这样的对象

{
  "name": "My Name",
  "createdBy": "Instance creator put this data"
}