title: Avoiding code duplication among gson deserializers
body: <p>I have a number of related objects which I am using gson to deserialize. Currently, each of the deserializers fully implements deserialization by themselves.</p>
  
  <p>I want to figure out how to minimize the code duplication among them, possibly by dividing the work among multiple deserializers.</p>
  
  <p>These are some examples I've already implemented and use:</p>
  
  <pre><code>public static class WeaponDeserializer implements JsonDeserializer&lt;Weapon&gt; {
  
      @Override
      public Weapon deserialize(JsonElement json, Type typeOfT,
              JsonDeserializationContext context) throws JsonParseException {
          String name = context.deserialize(json.getAsJsonObject().get("name"), String.class);
          ItemQuality quality = json.getAsJsonObject().get("quality") != null ? context.deserialize(json.getAsJsonObject().get("quality"), ItemQuality.class) : ItemQuality.Common;
          Availability availability = context.deserialize(json.getAsJsonObject().get("availability"), Availability.class);
          String description = context.deserialize(json.getAsJsonObject().get("description"), String.class);
          double weight = json.getAsJsonObject().get("weight") != null ? json.getAsJsonObject().get("weight").getAsDouble() : 0.0;
          WeaponClass weaponClass = context.deserialize(json.getAsJsonObject().get("class"), WeaponClass.class);
          WeaponType weaponType = context.deserialize(json.getAsJsonObject().get("type"), WeaponType.class);
          String damage = context.deserialize(json.getAsJsonObject().get("damage"), String.class);
          String penetration = json.getAsJsonObject().get("pen").getAsString();
          String range = context.deserialize(json.getAsJsonObject().get("range"), String.class);
          String rateOfFire = context.deserialize(json.getAsJsonObject().get("rof"), String.class);
          int clip = json.getAsJsonObject().get("clip") != null ? context.deserialize(json.getAsJsonObject().get("clip"), Integer.class) : 0;
          String reload = context.deserialize(json.getAsJsonObject().get("reload"), String.class);
          Set&lt;String&gt; specialRules = context.deserialize(json.getAsJsonObject().get("special qualities"), new TypeToken&lt;Set&lt;String&gt;&gt;() {
          }.getType());
          Set&lt;UpgradeOrCustomization&gt; upgrades = json.getAsJsonObject().get("upgrades") != null ? context.deserialize(json.getAsJsonObject().get("upgrades"), new TypeToken&lt;Set&lt;UpgradeOrCustomization&gt;&gt;() {
          }.getType()) : Collections.EMPTY_SET;
  
          return new Weapon(name, quality, availability, description, weight, weaponClass, weaponType, damage, penetration, range, rateOfFire, clip, reload, specialRules, upgrades);
      }
  }
  </code></pre>
  
  
  
  <pre><code>    public static class WeaponDeserializer implements JsonDeserializer&lt;Weapon&gt; {
  
      @Override
      public Weapon deserialize(JsonElement json, Type typeOfT,
              JsonDeserializationContext context) throws JsonParseException {
          String name = context.deserialize(json.getAsJsonObject().get("name"), String.class);
          ItemQuality quality = json.getAsJsonObject().get("quality") != null ? context.deserialize(json.getAsJsonObject().get("quality"), ItemQuality.class) : ItemQuality.Common;
          Availability availability = context.deserialize(json.getAsJsonObject().get("availability"), Availability.class);
          String description = context.deserialize(json.getAsJsonObject().get("description"), String.class);
          double weight = json.getAsJsonObject().get("weight") != null ? json.getAsJsonObject().get("weight").getAsDouble() : 0.0;
          WeaponClass weaponClass = context.deserialize(json.getAsJsonObject().get("class"), WeaponClass.class);
          WeaponType weaponType = context.deserialize(json.getAsJsonObject().get("type"), WeaponType.class);
          String damage = context.deserialize(json.getAsJsonObject().get("damage"), String.class);
          String penetration = json.getAsJsonObject().get("pen").getAsString();
          String range = context.deserialize(json.getAsJsonObject().get("range"), String.class);
          String rateOfFire = context.deserialize(json.getAsJsonObject().get("rof"), String.class);
          int clip = json.getAsJsonObject().get("clip") != null ? context.deserialize(json.getAsJsonObject().get("clip"), Integer.class) : 0;
          String reload = context.deserialize(json.getAsJsonObject().get("reload"), String.class);
          Set&lt;String&gt; specialRules = context.deserialize(json.getAsJsonObject().get("special qualities"), new TypeToken&lt;Set&lt;String&gt;&gt;() {
          }.getType());
          Set&lt;UpgradeOrCustomization&gt; upgrades = new HashSet&lt;&gt;();
          for (JsonElement element : json.getAsJsonObject().get("upgrades") != null ? json.getAsJsonObject().get("upgrades").getAsJsonArray() : Collections.&lt;JsonElement&gt;emptySet()){
              upgrades.add(UpgradeOrCustomization.getByName(element.getAsString()));
          }
  
          return new Weapon(name, quality, availability, description, weight, weaponClass, weaponType, damage, penetration, range, rateOfFire, clip, reload, specialRules, upgrades);
      }
  }
  </code></pre>