2017-08-21 5 views
5

J'ai backend qui me renvoie un peu de json.Kotlin non nullable peut être nulle?

Je Parse à ma classe:

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

Utilisez l'usine de conversion de gson:

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

Et dans mon interface:

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

Puis-je récupérer des données à partir du serveur (avec rxJava) sans aucune erreur. Mais je m'y attendais une erreur parce que je pensais que je devais faire quelque chose comme ça (pour éviter les erreurs de conversion GSON, car notNullableValue n'est pas présent dans ma réponse JSON):

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

Une fois les données reçues de back-end et analysé à mon Classe SomeData avec constructeur sans valeur def, la valeur de notNullableValue == null.

Comme je comprends pas la valeur nullable peut être nulle dans Kotlin?

+0

S'il vous plaît voir si cela aide: https://stackoverflow.com/a/39963353/2196460 – hotkey

+0

Son expliquer situation avec valeur def dans le constructeur. Mais dans ma situation, je n'ai pas de valeur. – jQuick

+0

le 'notNullableValue' a été modifié par gson après avoir été créé. parce que c'est 'var' pas' val'. –

Répondre

9

Oui, c'est parce que vous lui donnez une valeur par défaut. Bien sûr, il ne sera jamais nul. C'est tout le point d'une valeur par défaut. Supprimez ="" du constructeur et vous obtiendrez une erreur.

Modifier: a trouvé le problème. GSON utilise la classe magique sun.misc.Unsafe qui a une méthode allocateInstance qui est évidemment considérée comme très unsafe parce que ce qu'elle fait est sauter l'initialisation (constructeurs/initialiseurs de champ et similaires) et les contrôles de sécurité. Donc, votre réponse est pourquoi un champ de Kotlin non nul peut être nul. Code Offending est com/google/gson/internal/ConstructorConstructor.java:223

Quelques détails intéressants au sujet de la classe Unsafe: http://mishadoff.com/blog/java-magic-part-4-sun-dot-misc-dot-unsafe/

+0

Non, comme vous avez lu tout fonctionne correctement sans = "". Et notNullableValue == null – jQuick

+0

Je suis désolé pour malentendu, je suis question d'édition. – jQuick

+0

@jQuick J'ai mis à jour ma réponse. TLDR: Gson utilise des classes magiques java dangereuses. – Strelok

0

Essayez de passer outre constructeur comme ceci:

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

Maintenant, après la réponse du serveur, vous pouvez vérifier la notNullableValue est non nul - son vide