2011-05-06 9 views
2

DecimalFormat番号を含むクラスをシリアル化しているコードがあります。これは2.3.4まで機能しました。どうすれば解決できますか?ここでDecimalFormatSymbolsを2.3.4でシリアル化する際の問題

ERROR/AndroidRuntime(684): java.lang.IllegalArgumentException: no char field 'exponential' 

は私がシリアライズ午前クラスです:

public class Quote implements Serializable { 

    private static final long serialVersionUID = 1L; 

    private String symbol; 
    private String name; 
    private String change; 
    private String percentChange; 
    private String open; 
    private String daysHigh; 
    private String daysLow; 
    private String dividendYield; 
    private String volume; 
    private String averageDailyVolume; 
    private String peRatio; 
    private String marketCapitalization; 
    private String yearHigh; 
    private String yearLow; 
    private String lastTradePriceOnly; 
    private DecimalFormat df = new DecimalFormat("#,###,###,###,###,##0.00"); 
    private DecimalFormat vf = new DecimalFormat("#,###,###,###,###,##0"); 

    public String getSymbol() { 
     return symbol; 
    } 
    public void setSymbol(String symbol) { 
     this.symbol = symbol; 
    } 
    public String getName() { 
     return name; 
    } 
    public void setName(String name) { 
     this.name = name; 
    } 
    public String getChange() { 
     return change; 
    } 
    public void setChange(String change) { 
     if(change.equals("null")){ 
      this.change = "N/A"; 
     } 
     else{ 
      float floatedChange = Float.valueOf(change); 
      this.change = (df.format(floatedChange)); 
     } 
    } 
    public String getPercentChange() { 
     return percentChange; 
    } 
    public void setPercentChange(String percentChange) { 
     if(percentChange.equals("null")) 
      percentChange = "N/A"; 
     else 
      this.percentChange = percentChange; 
    } 
    public String getOpen() { 
     return open; 
    } 
    public void setOpen(String open) { 
     if(open.equals("null")) 
      this.open = "N/A"; 
     else 
      this.open = open; 
    } 
    public String getDaysHigh() { 
     return daysHigh; 
    } 
    public void setDaysHigh(String daysHigh) { 
     if(daysHigh.equals("null")) 
      this.daysHigh = "N/A"; 
     else{ 
      float floatedDaysHigh = Float.valueOf(daysHigh); 
      this.daysHigh = (df.format(floatedDaysHigh)); 
     } 
    } 
    public String getDaysLow() { 
     return daysLow; 
    } 
    public void setDaysLow(String daysLow) { 
     if(daysLow.equals("null")) 
      this.daysLow = "N/A"; 
     else{ 
      float floatedDaysLow = Float.valueOf(daysLow); 
      this.daysLow = (df.format(floatedDaysLow)); 
     } 
    } 
    public String getVolume() { 
     return volume; 
    } 
    public void setVolume(String volume) { 
     if(volume.equals("null")){ 
      this.volume = "N/A"; 
     } 
     else{ 
      float floatedVolume = Float.valueOf(volume); 
      this.volume = (vf.format(floatedVolume)); 
     } 
    } 
    public String getDividendYield() { 
     return dividendYield; 
    } 
    public void setDividendYield(String dividendYield) { 
     if(dividendYield.equals("null")) 
      this.dividendYield = "N/A"; 
     else 
      this.dividendYield = dividendYield; 
    } 
    public String getAverageDailyVolume() { 
     return averageDailyVolume; 
    } 
    public void setAverageDailyVolume(String averageDailyVolume) { 
     if(averageDailyVolume.equals("null")){ 
      this.averageDailyVolume = "N/A"; 
     } 
     else{ 
      float floatedAverageDailyVolume = Float.valueOf(averageDailyVolume); 
      this.averageDailyVolume = (vf.format(floatedAverageDailyVolume)); 
     } 
    } 
    public String getPeRatio() { 
     return peRatio; 
    } 
    public void setPeRatio(String peRatio) { 
     if(peRatio.equals("null")) 
      this.peRatio = "N/A"; 
      else 
     this.peRatio = peRatio; 
    } 
    public String getMarketCapitalization() { 
     return marketCapitalization; 
    } 
    public void setMarketCapitalization(String marketCapitalization) { 
     if(marketCapitalization.equals("null")) 
      this.marketCapitalization = "N/A"; 
     else 
      this.marketCapitalization = marketCapitalization; 
    } 
    public String getYearHigh() { 
     return yearHigh; 
    } 
    public void setYearHigh(String yearHigh) { 
     if(yearHigh.equals("null")) 
      this.yearHigh = "N/A"; 
     else 
      this.yearHigh = yearHigh; 
    } 
    public String getYearLow() { 
     return yearLow; 
    } 
    public void setYearLow(String yearLow) { 
     if(yearLow.equals("null")) 
      this.yearLow = "N/A"; 
     else 
      this.yearLow = yearLow; 
    } 

    public String getLastTradePriceOnly() { 
     return lastTradePriceOnly; 
    } 

    public void setLastTradePriceOnly(String lastTradePriceOnly) { 
     if(lastTradePriceOnly.equals("null")){ 
      this.lastTradePriceOnly = "N/A"; 
     } 
     else{ 
      float floatedLastTradePriceOnly = Float.valueOf(lastTradePriceOnly); 
      this.lastTradePriceOnly = (df.format(floatedLastTradePriceOnly)); 
     } 
    } 

    @Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     result = prime * result + ((change == null) ? 0 : change.hashCode()); 
     result = prime * result 
       + ((daysHigh == null) ? 0 : daysHigh.hashCode()); 
     result = prime * result + ((daysLow == null) ? 0 : daysLow.hashCode()); 
     result = prime 
       * result 
       + ((lastTradePriceOnly == null) ? 0 : lastTradePriceOnly 
         .hashCode()); 
     result = prime 
       * result 
       + ((marketCapitalization == null) ? 0 : marketCapitalization 
         .hashCode()); 
     result = prime * result + ((name == null) ? 0 : name.hashCode()); 
     result = prime * result + ((open == null) ? 0 : open.hashCode()); 
     result = prime * result + ((peRatio == null) ? 0 : peRatio.hashCode()); 
     result = prime * result 
       + ((percentChange == null) ? 0 : percentChange.hashCode()); 
     result = prime * result + ((symbol == null) ? 0 : symbol.hashCode()); 
     result = prime * result + ((volume == null) ? 0 : volume.hashCode()); 
     result = prime * result 
       + ((yearHigh == null) ? 0 : yearHigh.hashCode()); 
     result = prime * result + ((yearLow == null) ? 0 : yearLow.hashCode()); 
     return result; 
    } 
    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) 
      return true; 
     if (obj == null) 
      return false; 
     if (getClass() != obj.getClass()) 
      return false; 
     Quote other = (Quote) obj; 
     if (change == null) { 
      if (other.change != null) 
       return false; 
     } else if (!change.equals(other.change)) 
      return false; 
     if (daysHigh == null) { 
      if (other.daysHigh != null) 
       return false; 
     } else if (!daysHigh.equals(other.daysHigh)) 
      return false; 
     if (daysLow == null) { 
      if (other.daysLow != null) 
       return false; 
     } else if (!daysLow.equals(other.daysLow)) 
      return false; 
     if (lastTradePriceOnly == null) { 
      if (other.lastTradePriceOnly != null) 
       return false; 
     } else if (!lastTradePriceOnly.equals(other.lastTradePriceOnly)) 
      return false; 
     if (marketCapitalization == null) { 
      if (other.marketCapitalization != null) 
       return false; 
     } else if (!marketCapitalization.equals(other.marketCapitalization)) 
      return false; 
     if (name == null) { 
      if (other.name != null) 
       return false; 
     } else if (!name.equals(other.name)) 
      return false; 
     if (open == null) { 
      if (other.open != null) 
       return false; 
     } else if (!open.equals(other.open)) 
      return false; 
     if (peRatio == null) { 
      if (other.peRatio != null) 
       return false; 
     } else if (!peRatio.equals(other.peRatio)) 
      return false; 
     if (percentChange == null) { 
      if (other.percentChange != null) 
       return false; 
     } else if (!percentChange.equals(other.percentChange)) 
      return false; 
     if (symbol == null) { 
      if (other.symbol != null) 
       return false; 
     } else if (!symbol.equals(other.symbol)) 
      return false; 
     if (volume == null) { 
      if (other.volume != null) 
       return false; 
     } else if (!volume.equals(other.volume)) 
      return false; 
     if (yearHigh == null) { 
      if (other.yearHigh != null) 
       return false; 
     } else if (!yearHigh.equals(other.yearHigh)) 
      return false; 
     if (yearLow == null) { 
      if (other.yearLow != null) 
       return false; 
     } else if (!yearLow.equals(other.yearLow)) 
      return false; 
     return true; 
    } 
} 

そして、ここでは私のシリアル化操作は、(ノート引用符は、配列リストである)である:

private void serializeQuotes() { 
     FileOutputStream fos; 
     try { 
      fos = openFileOutput(Constants.FILENAME, Context.MODE_PRIVATE); 
      ObjectOutputStream oos = new ObjectOutputStream(fos); 
      oos.writeObject(quotes); //this is an ArrayList<Quote> 
      oos.close(); 
     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

答えて

1

なぜあなたはシリアル化されていますDecimalFormat?インスタンスDecimalFormatのフィールドをstaticのフィールドに置き換えます。並行性が問題となる場合は、static ThreadLocal<DecimalFormat>を使用します。

public class Quote implements Serializable { 

    private static final long serialVersionUID = 1L; 

    private String symbol; 
    private String name; 
    private String change; 
    private String percentChange; 
    private String open; 
    private String daysHigh; 
    private String daysLow; 
    private String dividendYield; 
    private String volume; 
    private String averageDailyVolume; 
    private String peRatio; 
    private String marketCapitalization; 
    private String yearHigh; 
    private String yearLow; 
    private String lastTradePriceOnly; 


    private static final ThreadLocal<DecimalFormat> df = new ThreadLocal<DecimalFormat> { 
     @Override 
     protected DecimalFormat initialValue() { 
      return new DecimalFormat("#,###,###,###,###,##0.00"); 
     } 
    } 

    private static final ThreadLocal<DecimalFormat> vf = new ThreadLocal<DecimalFormat> { 
     @Override 
     protected DecimalFormat initialValue() { 
      return new DDecimalFormat("#,###,###,###,###,##0"); 
     } 
    } 

    // snip... 

} 

http://download.oracle.com/javase/6/docs/api/java/lang/ThreadLocal.html

+0

私はファイルシステムに値を保存するための要件を持っているので、私はのDecimalFormatをシリアル化しています。 –

+0

はい、しかし、 'DecimalFormat'フィールドは、あなたが提供したコードで定数です。それらは 'final'と宣言でき、コードは他の変更を加えずにコンパイルされます。それらは 'equals()'や 'hashCode()'では使われません。彼らはどんなゲッターを通しても見えません。それらはすべてのインスタンスでまったく同じです。それらは他の値を適合させるためにのみ使用されます。並行性が考慮されていない場合、それらは 'static''と' final'になり、他のコードは変更されません。各DecimalFormatのインスタンスが複数必要になる唯一の理由は、オブジェクトがスレッドセーフでないためです。 –

関連する問題