首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Java 深度克隆:正確複製 InputStream 等引用類型屬性

     編輯:程式設計疑難解答

問題現象

實作 Cloneable 介面並覆寫 clone() 方法,但發現克隆後的對象中 InputStream 屬性仍指向同一個物件(淺拷貝),修改其中一個會影響另一個。

原因

super.clone() 僅執行淺拷貝:基本類型複製值,引用類型複製引用地址。JVM 不會自動深度複製引用指向的對象(如 InputStream、自定義對象等)。

解決方案:手動實現深度拷貝

在 clone() 中將 InputStream 讀取到 ByteArrayOutputStream,再構建新的 ByteArrayInputStream 賦值給克隆對象:

@Override
public Object clone() throws CloneNotSupportedException {
    CloneTest cloneTest = (CloneTest) super.clone();
    // 深度複製 InputStream
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024];
    int len;
    try {
        while ((len = inputStream.read(buffer)) != -1) {
            baos.write(buffer, 0, len);
        }
        baos.flush();
        // 建立新的輸入流
        cloneTest.inputStream = new ByteArrayInputStream(baos.toByteArray());
    } catch (IOException e) {
        e.printStackTrace();
        throw new CloneNotSupportedException("InputStream 複製失敗: " + e.getMessage());
    }
    return cloneTest;
}

注意事項

  • 原 InputStream 必須可讀且非無限流(如網絡流需先緩存)。
  • 大流量數據建議使用臨時文件而非記憶體緩存,避免 OOM。
  • 若類中還有其他引用類型屬性(如 List、自定義對象),同樣需逐一深度複製。

總結

Java 原生 clone() 只做淺拷貝。對於 InputStream、集合、自定義對象等引用類型,必須在 clone() 中顯式編碼實現深度拷貝,確保克隆對象與原對象完全獨立。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved