Ich habe eine Klasse A, die einige private Felder hat, und dieselbe Klasse erweitert eine andere Klasse B, die auch einige private Felder hat, die in Klasse A sind.
public class A extends B {
private BigDecimal netAmountTcy;
private BigDecimal netAmountPcy;
private BigDecimal priceTo;
private String segment;
private BigDecimal taxAmountTcy;
private BigDecimal taxAmountPcy;
private BigDecimal tradeFeesTcy;
private BigDecimal tradeFeesPcy;
// getter and setter for the above fields
}
und Klasse B hat einige private Felder, die in Klasse A sind
Wenn ich jetzt versuche, eine JSON-Zeichenfolge aus der obigen Klasse A zu erstellen, erhalte ich die folgende Ausnahme:
class com.hexgen.ro.request.A declares multiple JSON fields named netAmountPcy
Wie kann man das beheben?
Da es sich um private Felder handelt, sollte es beim Erstellen von JSON-Strings kein Problem geben, denke ich, aber ich bin mir nicht sicher.
Ich erstelle JSON-String wie folgt:
Gson gson = new Gson();
tempJSON = gson.toJson(obj);
hier ist obj das Objekt der Klasse A
Poste deine Superklasse B.
– NPKR
10. Mai 2013 um 7:08 Uhr
Da es sich um private Felder handelt, sollte es beim Erstellen von JSON-Strings keine Probleme geben
Ich glaube nicht, dass diese Aussage wahr ist, GSON schlägt beim Serialisieren die privaten Felder des Objekts nach, was bedeutet, dass alle privaten Felder der Oberklasse enthalten sind, und wenn Sie Felder mit demselben Namen haben, wird ein Fehler ausgegeben.
Wenn Sie ein bestimmtes Feld nicht einschließen möchten, müssen Sie es mit markieren transient Stichwort, zB:
private transient BigDecimal tradeFeesPcy;
Danke es funktioniert. Aber warum funktioniert die @Expose-Annotation von Gson nicht mit dem Feld der Oberklasse und sorgt für Verwirrung?
– Facher
19. Mai 2017 um 15:19 Uhr
@Fakher zu bekommen @Expose richtig funktioniert, müssen Sie einstellen @Expose(serialize = false)und unbedingt anrufen excludeFieldsWithoutExposeAnnotation()auf Ihrem GsonBuilder Objekt.
– Ibrahim.H
12. Februar 2018 um 10:49 Uhr
Dieser Kommentar hat mein Problem perfekt gelöst. Verwenden new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create().toJson(YOUR_OBJECT)Es klappt
– Zweck PI
22. Juli 2019 um 4:55 Uhr
Wenn Sie mit Kotlin arbeiten, gibt es dafür eine Anmerkung: kotlin /** * Marks the JVM backing field of the annotated property as `transient`, meaning that it is not * part of the default serialized form of the object. */ @Target(FIELD) @Retention(AnnotationRetention.SOURCE) @MustBeDocumented public actual annotation class Transient
– AouledIssa
10. Oktober 2020 um 20:48 Uhr
Das ist ein bisschen spät, aber ich bin auch auf genau das gleiche Problem gestoßen. Das einzige war, dass ich die Oberklasse nicht ändern konnte, da dieser Code nicht von mir stammte. Ich habe dies gelöst, indem ich eine Ausschlussstrategie erstellt habe, die jedes Feld übersprungen hat, das ein Feld mit demselben Namen in einer Oberklasse hatte. Hier ist mein Code für diese Klasse:
Dies ist die richtige Antwort, da ich das Objekt der Superklasse nicht von der Serialisierung ausschließen möchte, ich möchte nur nicht, dass GSON die Variable der erweiterten Klasse ausschließt
– CQM
28. Februar 2014 um 17:07 Uhr
Meiner Meinung nach ist das der falsche Weg. Auf diese Weise enthält Ihr JSON die Variable aus der Superklasse und der Wert der Unterklasse wird ausgeblendet. Man würde es umgekehrt erwarten; die Unterklassenvariable in json haben und die Oberklassenvariable ausblenden.
– Veden
9. Dezember 2015 um 12:57 Uhr
@Veda, hast du eine umgekehrte Lösung gefunden? Ich stehe vor der gleichen Situation, in der ich untergeordnete Variablen und Werte benötige.
– Lernender
22. März 2018 um 17:03 Uhr
Ich denke, um das Gegenteil zu tun, müssen Sie wissen, ob der Typ, den Sie betrachten, der Untertyp eines anderen Typs ist. Es scheint viel schwieriger zu sein (wenn es überhaupt möglich ist), den Vererbungsbaum von der anderen Seite nach oben zu schauen. stackoverflow.com/questions/492184/…
– jokul
6. August 2018 um 20:09 Uhr
Die akzeptierte Antwort funktioniert besser. Wenn die oberste Klasse das Feld als transient markiert, obwohl es den gleichen Namen wie die untere Klasse hat, wird es von der Serialisierung ausgeschlossen.
– CompEng88
20. September 2019 um 21:12 Uhr
Gangnus
Dieselbe Fehlermeldung tritt auch auf, wenn Sie unterschiedliche Felder haben, diese aber gleich sind @SerializedName.
@SerializedName("date_created")
private Date DateCreated;
@SerializedName("date_created")
private Integer matchTime;
Beim Kopieren / Einfügen können Sie einfach einen solchen Fehler machen. Schauen Sie also in die Klasse und seine Vorfahren und prüfe das.
Sie können nicht zwei Felder mit demselben Namen haben.
Sie können nicht zwei Felder mit demselben serialisierten Namen haben.
Typen sind für diese Regeln irrelevant.
Was ist, wenn meine JSON-Datei tatsächlich denselben Namen mit unterschiedlichen Typen hat (absichtlich)? dh einige Endpunkte “main_id” ist ein Int, einige andere Endpunkte “main_id” ist ein String
– Ben Akin
1. Juni 2020 um 5:28 Uhr
1. Sie können nicht zwei Felder mit demselben Namen haben. 2. Sie können nicht zwei Felder mit demselben serialisierten Namen haben. 3. Typen sind in diesen Regeln irrelevant.
– Gangnus
1. Juni 2020 um 8:48 Uhr
Bei mir funktioniert nur diese Lösung.
– Ahamadullah Saikat
19. Mai um 9:42 Uhr
Saif
ich benutzte GsonBuilder und ExclusionStrategy Um die redundanten Felder wie unten zu vermeiden, ist es einfach und unkompliziert.
Fügen Sie die folgenden Zeilen am Ende von proguard.config hinzu (wenn Sie proguard im Projekt verwenden)
-keepclassmembers class * {
private <fields>;
}
Rakesch
In meinem Fall war ich dumm genug, einen Adapter mit der X-Klasse zu registrieren und zu versuchen, fromJson mit der Y-Klasse zu serialisieren:
final GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Game.class, new TournamentSerializer());
final Gson gson = gsonBuilder.create();
createdTournament = gson.fromJson(jsonResponse.toString(), Tournament.class);
REM-Code
In kotlin Hinzufügen der @Transient Die Anmerkung für die Variable in der übergeordneten Klasse hat bei a den Trick für mich getan sealed Klasse mit offenen Variablen.
das funktioniert in Kotlin für mich. Danke
– Bob Redity
27. Mai um 11:57 Uhr
Andere Antworten haben mehr Upvotes, aber diese Antwort bekommt meine. Ich hatte offene Werte für eine abstrakte Basisklasse, die ich in einer Unterklasse überschrieb. Das verwirrte Gson. @Transient in den offenen Eigenschaften der Basisklasse behebt dies.
– Weißt du
20. Juli um 21:00 Uhr
12456400cookie-checkKlasse A deklariert mehrere JSON-Felderyes
Poste deine Superklasse B.
– NPKR
10. Mai 2013 um 7:08 Uhr