Как заставить Kotlin с помощью gson.fromJson () вызвать мой инициализатор класса? - PullRequest
0 голосов
/ 16 февраля 2019

В проекте 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!

Разве это нельзя назвать?Это пример моего класса, верно?

Если нет, есть ли способ заставить init {...}?Или я должен вызывать публичный метод (как я делал в моем примере?)

1 Ответ

0 голосов
/ 17 февраля 2019

Вы можете сделать это, используя 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"
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...