如何使用Gson反序列化继承的Kotlin数据类

时间:2017-04-23 20:14:35

标签: json inheritance gson kotlin data-class

在Android应用程序中,我需要使用单个抽象级别对Kotlin数据类的Json数据进行反序列化。但我不知道在构造函数中放置正确的属性。

作为一个简单的版本,让我们说我有一个形状:

#include <avr/io.h>
#include <util/delay.h>

#define FOSC 8000000// Clock Speed
#define BAUD 9600
#define MYUBRR FOSC/16/BAUD-1

void USART_Init( unsigned int ubrr );
void USART_Transmit( unsigned char data );
unsigned char USART_Receive( void );

int main( void )
{
    unsigned char str[5] = "serus";
    unsigned char strLenght = 5;
    unsigned int i = 47;

    USART_Init ( MYUBRR );
    //USART_Transmit('S' );
    while(1)
    {
        /*USART_Transmit( str[i++] );
        if(i >= strLenght)
        i = 0;*/
        USART_Transmit(i);
        _delay_ms(250);
    }
    return(0);
}

void USART_Init( unsigned int ubrr )
{
    /* Set baud rate */
    UBRR0H = (unsigned char)(ubrr>>8);
    UBRR0L = (unsigned char)ubrr;
    /* Enable receiver and transmitter */
    UCSR0B = (1<<RXEN)|(1<<TXEN);
    /* Set frame format: 8data, 2stop bit */
    UCSR0C = (1<<USBS)|(3<<UCSZ0);
}

void USART_Transmit( unsigned int data )
{
    /* Wait for empty transmit buffer */
    while ( !( UCSR0A & (1<<UDRE)) )
    ;
    /* Put data into buffer, sends the data */
    UDR0 = data;
}

unsigned char USART_Receive( void )
{
    /* Wait for data to be received */
    while ( !(UCSR0A & (1<<RXC)) )
    ;
    /* Get and return received data from buffer */
    return UDR0;
}

有两个派生

abstract class Shape(open val x: Int, open val y: Int)

data class Circle(val radius: Int, override val x: Int, override val y: Int): Shape(x, y)

所以我的目标是,不要实例化一个Shape。因此,请始终反序列化其派生。后来我需要在其他类中处理一些集合属性,如:

data class Square(val width: Int, override val x: Int, override val y: Int): Shape(x, y)

但我也必须知道每个元素的派生类型。

当我尝试用Gson反序列化给定的例子时

val shapes: List<Shape>

我总是得到一个IllegalArgumentException

val square = gson.fromJson(SQUARE_JSON, Square::class.java)

是否有可能在不编写自定义Gson TypeAdapter或丢失数据类优势的情况下正确反序列化此类?

由于

3 个答案:

答案 0 :(得分:9)

ShapeSquare都声明了字段xySquare的实例实际上存储了xy两次的值。为避免这种情况,您可以从x构造函数中删除yShape,并将其声明为abstractCircle例如:

也是如此
abstract class Shape {
    abstract val x: Int
    abstract val y: Int
}

data class Circle(val radius: Int, override val x: Int, override val y: Int) : Shape()

data class Square(val width: Int, override val x: Int, override val y: Int) : Shape()

Gson现在可以成功序列化和反序列化CircleSquare个对象。

答案 1 :(得分:1)

你确定数据类是Gson问题吗?它应该正确使用它们,只有非可空字段可能是一个问题。

您的错误表示您的字段名称相同。
如果您想要包含任何特定字段,则必须使用@Transient

对其进行注释

答案 2 :(得分:1)

如果你还没有能够将基类转换为Kotlin,那么@Transient注释对我有效。

data class Circle(val radius: Int, 
    @Transient val x: Int, 
    @Transient val y: Int): Shape(x, y)

data class Square(val width: Int, 
    @Transient val x: Int, 
    @Transient val y: Int): Shape(x, y)