2017-08-21 32 views
5

Mam backend, który zwraca mi trochę jsona.Kotlin nie wartość zerowalna może być pusty?

I analizować je do mojej klasy:

class SomeData(
    @SerializedName("user_name") val name: String, 
    @SerializedName("user_city") val city: String, 
    var notNullableValue: String) 

użytku fabrycznego konwerter gson:

Retrofit retrofit = new Retrofit.Builder() 
    .baseUrl(ENDPOINT) 
    .client(okHttpClient) 
    .addConverterFactory(GsonConverterFactory.create(gson)) 
    .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) 
    .build(); 

I w moim interfejsu:

interface MyAPI { 
    @GET("get_data") 
    Observable<List<SomeData>> getSomeData(); 
} 

Potem pobierać dane z serwera (z rxJava) bez żadnego błędu. Ale spodziewałem się błąd, ponieważ myślałem, że powinienem zrobić coś takiego (aby zapobiec błąd konwertera GSON, ponieważ notNullableValue nie jest obecny w moim odpowiedzi JSON):

class SomeData @JvmOverloads constructor(
    @SerializedName("user_name") val name: String, 
    @SerializedName("user_city") val city: String, 
var notNullableValue: String = "") 

Po odbiorze danych z backend i analizowany na moje Klasa SomeData z konstruktorem bez wartości def, wartość notNullableValue == null.

Jak rozumiem, wartość zerowa może być zerowa w Kotlin?

+0

Proszę sprawdzić, czy to pomaga: https://stackoverflow.com/a/39963353/2196460 – hotkey

+0

jego wyjaśnienia sytuacja z wartością def w konstruktorze. Ale w mojej sytuacji mam wadę. – jQuick

+0

zmienna 'notNullableValue' została zmieniona przez gson po utworzeniu. ponieważ jest 'var' nie' val'. –

Odpowiedz

9

Tak, to dlatego, że nadajesz mu wartość domyślną. Oczywiście nigdy nie będzie to zero. To jest cały punkt wartości domyślnej.

Usuń ="" z konstruktora, a otrzymasz błąd.

Edytuj: Znaleziono błąd. GSON używa klasy magicznej sun.misc.Unsafe, która ma metodę allocateInstance, która jest oczywiście uważana za bardzo unsafe, ponieważ to, co robi, omija inicjalizację (konstruktory/inicjatory polowe i tym podobne) i kontrole bezpieczeństwa. Tak więc jest twoja odpowiedź, dlaczego pole nie-zerowujące Kotlin może być puste. Kod Offending jest w com/google/gson/internal/ConstructorConstructor.java:223

kilka interesujących szczegółów o klasie Unsafe: http://mishadoff.com/blog/java-magic-part-4-sun-dot-misc-dot-unsafe/

+0

Nie, ponieważ przeczytałeś poprawnie wszystkie prace dobrze bez "" ". I notNullableValue == null – jQuick

+0

Przepraszam za nieporozumienie, jestem pytanie edycji. – jQuick

+0

@jQuick Zaktualizowałem swoją odpowiedź. TLDR: Gson używa niebezpiecznych klas magii java. – Strelok

0

Spróbuj nadpisać konstruktor tak:

class SomeData(
     @SerializedName("user_name") val name: String, 
     @SerializedName("user_city") val city: String, 
     var notNullableValue: String = "") { 
    constructor() : this("","","") 
} 

Teraz po odpowiedzi serwera można sprawdzić notNullableValue nie jest null - jego pusty

Powiązane problemy