最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java四種拷貝方式實戰(zhàn)總結(jié)(一文掃清所有拷貝問題)

 更新時間:2025年07月11日 10:43:10   作者:小W求學(xué)之旅  
在Java中文件拷貝可以通過多種方式實現(xiàn),不同方式的性能和適用場景有所差異,文中通過代碼介紹的非常詳細(xì),這篇文章主要介紹了Java四種拷貝方式的相關(guān)資料,需要的朋友可以參考下

前言

作為Java開發(fā)者,日常開發(fā)中經(jīng)常會遇到數(shù)據(jù)拷貝的需求。最近在面試中也有被問到一次大文件拷貝,抽空專門總結(jié)一下,從基礎(chǔ)概念到實戰(zhàn)技巧,配合流程圖,讓原理和流程一目了然~

一、淺拷貝VS深拷貝

一開始做spring項目時,就被淺拷貝坑過。當(dāng)時想復(fù)制一個對象,結(jié)果改了新對象的屬性,老對象也跟著變了。后來才知道,這就是淺拷貝的“鍋”。

淺拷貝就像拍證件照,照片上的人看著和你一模一樣,但本質(zhì)上還是兩張紙。Java里的淺拷貝只會復(fù)制對象的基本屬性,遇到引用類型(比如自定義類),就直接把地址抄過來。所以你改新對象里的引用屬性,老對象也會跟著遭殃。

深拷貝就靠譜多了,它會把對象里里外外都復(fù)制一遍,就像克隆人,新對象和老對象完全獨立。雖然麻煩點,但勝在安全,適合處理復(fù)雜對象。

舉個例子,有個Person類包含nameAddress屬性:

class Address {
    String city;
}

class Person {
    String name;
    Address address;

    // 淺拷貝
    Person shallowCopy() {
        Person copy = new Person();
        copy.name = this.name;
        copy.address = this.address;
        return copy;
    }

    // 深拷貝
    Person deepCopy() {
        Person copy = new Person();
        copy.name = this.name;
        copy.address = new Address();
        copy.address.city = this.address.city;
        return copy;
    }
}

二、大文件拷貝:別讓你的程序“龜速運(yùn)行”

之前做文件上傳功能,用傳統(tǒng)IO方式拷貝大文件,結(jié)果服務(wù)器直接卡住。后來換成NIO,速度直接起飛!

傳統(tǒng)IO就像螞蟻搬家,一次搬一點,頻繁讀寫磁盤;NIO則像卡車運(yùn)輸,直接把數(shù)據(jù)從一個地方搬到另一個地方,速度快得多。

// 傳統(tǒng)IO方式,適合小文件
public static void copyFileByIO(File source, File dest) throws IOException {
    try (InputStream is = new FileInputStream(source);
         OutputStream os = new FileOutputStream(dest)) {
        byte[] buffer = new byte[1024];
        int len;
        while ((len = is.read(buffer)) != -1) {
            os.write(buffer, 0, len);
        }
    }
}

// NIO方式,適合大文件
public static void copyFileByNIO(File source, File dest) throws IOException {
    try (FileChannel sourceChannel = new FileInputStream(source).getChannel();
         FileChannel destChannel = new FileOutputStream(dest).getChannel()) {
        destChannel.transferFrom(sourceChannel, 0, sourceChannel.size());
    }
}

三、對象拷貝的進(jìn)階方案:使用造好的輪子

手動寫深拷貝代碼太麻煩?別慌,Java提供給我們有不少寫好的辦法。

1. 序列化與反序列化

就像把對象打包成快遞,寄出去再拆開。雖然速度慢點,但能保證完全獨立的拷貝。不過要注意,所有相關(guān)類都得實現(xiàn)Serializable接口。

public static <T extends Serializable> T deepCopyBySerialization(T obj) {
    try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
         ObjectOutputStream oos = new ObjectOutputStream(baos)) {
        oos.writeObject(obj);
        try (ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
             ObjectInputStream ois = new ObjectInputStream(bais)) {
            return (T) ois.readObject();
        }
    } catch (IOException | ClassNotFoundException e) {
        throw new RuntimeException(e);
    }
}

2. JSON序列化

用Jackson或Gson把對象轉(zhuǎn)成JSON字符串,再轉(zhuǎn)回來,簡單粗暴。不過這種方式要求對象的屬性都能被JSON正確解析。

import com.fasterxml.jackson.databind.ObjectMapper;

public static <T> T deepCopyByJSON(T obj, Class<T> clazz) {
    try {
        ObjectMapper mapper = new ObjectMapper();
        String json = mapper.writeValueAsString(obj);
        return mapper.readValue(json, clazz);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

四、數(shù)組和集合的拷貝

數(shù)組的clone()方法看似簡單,實則暗藏玄機(jī):基本類型數(shù)組用它是深拷貝,對象數(shù)組就是淺拷貝。

int[] intArray = {1, 2, 3};
int[] copiedIntArray = intArray.clone(); // 深拷貝

Person[] personArray = new Person[2];
Person[] copiedPersonArray = personArray.clone(); // 淺拷貝

集合類的構(gòu)造函數(shù)也是淺拷貝,比如new ArrayList<>(originalList)。想深拷貝集合,得手動遍歷每個元素。

List<Person> originalList = new ArrayList<>();
List<Person> deepCopiedList = originalList.stream()
        .map(Person::deepCopy)
        .collect(Collectors.toList());

五、第三方庫:站在巨人的肩膀上

不想自己造輪子?Apache Commons Lang和Dozer能幫你大忙。前者提供了便捷的序列化拷貝工具,后者擅長對象屬性映射,用起來超方便。

<!-- Apache Commons Lang依賴 -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.12.0</version>
</dependency>

// 使用示例
Person copiedPerson = SerializationUtils.clone(originalPerson);

六、總結(jié):看不同場景選擇合適的拷貝方式

  • 簡單對象用淺拷貝,復(fù)雜對象用深拷貝
  • 大文件優(yōu)先用NIO,小文件用傳統(tǒng)IO
  • 能偷懶就偷懶,善用第三方庫
  • 多寫測試用例,別讓拷貝“埋雷”

到此這篇關(guān)于Java四種拷貝方式實戰(zhàn)文章就介紹到這了,更多相關(guān)Java四種拷貝方式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

石门县| 象州县| 临邑县| 长春市| 固原市| 长春市| 张家界市| 广安市| 望谟县| 海阳市| 河西区| 彭州市| 昌图县| 长泰县| 叶城县| 贵南县| 文登市| 阳东县| 岳池县| 仲巴县| 文安县| 额尔古纳市| 阿克| 高雄县| 类乌齐县| 怀宁县| 卢氏县| 宁德市| 西贡区| 镇雄县| 义乌市| 广宗县| 平果县| 通辽市| 加查县| 长顺县| 桂平市| 东乌珠穆沁旗| 武隆县| 龙游县| 苍梧县|