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

Java8并發(fā)新特性CompletableFuture

 更新時間:2022年06月04日 08:52:07   作者:??生命猿于運動????  
這篇文章主要介紹了Java8并發(fā)新特性CompletableFuture,CompletableFuture針對Future接口做了改進,相比Callable/Runnable接口它支持多任務進行鏈式調用、組合、多任務并發(fā)處理,下面文章更多相關內(nèi)容得介紹,需要的小伙伴可以參考一下

1.CompletableFuture是什么?

各位小伙伴是否有一種感覺,整天大量時間沉迷于業(yè)務開發(fā)的同時,缺少對于一些技術更新的關注,忽略掉了很多實用又簡單的方法,以往我們做異步任務的時候都習慣于使用Callable或者Runnable接口去實現(xiàn),今天我們就來聊聊與之不同的CompletableFuture類。

CompletableFuture針對Future接口做了改進,相比Callable/Runnable接口它支持多任務進行鏈式調用、組合、多任務并發(fā)處理。很多時候我們在設計過程中會想在一個異步任務執(zhí)行完成后,直接獲取它的結果傳遞給下一個任務繼續(xù)執(zhí)行后續(xù)的流程,這時候CompletableFuture的作用就來了。

CompletableFuture類關系圖:

從以下類圖可以看到,CompletableFuture實現(xiàn)了Future和CompletionStage兩個接口,F(xiàn)uture提供了獲取任務執(zhí)行結果和任務執(zhí)行狀態(tài)的功能。 CompletionStage表示一個任務的執(zhí)行階段,提供了諸多方法支持了多任務的聚合功能。

2.CompletableFuture的方法使用說明

2.1 CompletableFuture類提供幾個靜態(tài)方法來進行異步操作

supplyAsync與runAsync主要用于構建異步事件。

supplyAsync帶有返回值的異步任務,支持在默認線程池ForkJoinPool.commonPool()中完成異步任務,也可以使用自定義線程池執(zhí)行異步任務,結果返回一個新的CompletableFuture,返回結果類型U。最終的任務執(zhí)行結果可通過返回CompletableFuture對象的 get()/join() 方法獲取返回值。

// 使用默認線程池
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) {...}
// 使用自定義線程池Executor
public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor) {...}

// ====================================demo華麗分割線============================================
CompletableFuture<String> supplyAsyncFuture = CompletableFuture.supplyAsync(() -> {
    log.info("executing supplyAsync task ...");
    return "this is supplyAsync";
});
// 進入阻塞獲取異步任務結果
log.info(supplyAsyncFuture.get());  // 輸出結果:this is supplyAsync

runAsync不帶返回值的異步任務,支持在默認線程池ForkJoinPool.commonPool()中完成異步任務,也可以使用自定義線程池執(zhí)行異步任務,結果返回一個新的CompletableFuture,返回結果類型為Void,也就是無返回值。

public static CompletableFuture<Void> runAsync(Runnable runnable) {...}
public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor) {...}

// ====================================demo華麗分割線============================================
CompletableFuture<Void> runAsyncFuture = CompletableFuture.runAsync(() -> {
    log.info("executing runAsync task ...");
});
runAsyncFuture.get();

allOf:多個CompletableFuture任務并發(fā)執(zhí)行,所有CompletableFuture任務完成時,返回一個新的CompletableFuture對象,其返回值為Void,也就是無返回值。

public static CompletableFuture<Void> allOf(CompletableFuture<?>... cfs) {...}

// ====================================demo華麗分割線============================================
// allOf,可傳遞返回值不同類型的future,最終結果按自己設計預期處理即可
CompletableFuture<String> cf11 = CompletableFuture.supplyAsync(() -> {
    log.info("executing supplyAsync task cf11 ...");
    return "this is supplyAsync";
});
CompletableFuture<String> cf12 = CompletableFuture.supplyAsync(() -> {
    log.info("executing supplyAsync task cf12 ...");
    return "this is supplyAsync";
});
CompletableFuture<Void> allOfFuture = CompletableFuture.allOf(cf11, cf12);
allOfFuture.get();

anyOf:多個CompletableFuture任務并發(fā)執(zhí)行,只要有一個CompletableFuture任務完成時,就會返回一個新的CompletableFuture對象,并返回該CompletableFuture執(zhí)行完成任務的返回值。

public static CompletableFuture<Object> anyOf(CompletableFuture<?>... cfs) {...}

// ====================================demo華麗分割線============================================
CompletableFuture<String> cf21 = CompletableFuture.supplyAsync(() -> {
    log.info("executing supplyAsync task cf21 ...");
    return "this is supplyAsync cf21";
});
CompletableFuture<String> cf22 = CompletableFuture.supplyAsync(() -> {
    log.info("executing supplyAsync task cf22 ...");
    return "this is supplyAsync cf22";
});
CompletableFuture<Object> anyOfFuture = CompletableFuture.anyOf(cf21, cf22);
log.info("{}", anyOfFuture.get());  // 輸出結果:this is supplyAsync cf21或cf22

2.2 獲取異步任務執(zhí)行結果的方法 get()/join()

join()和get()方法都是CompletableFuture對象基于阻塞的方式來獲取異步任務執(zhí)行結果。

  • get方法會拋出顯示異常必須捕獲處理,任務允許被中斷拋出InterruptedException異常,通過帶有超時時間的阻塞方式獲取異步任務執(zhí)行結果,超時等待無結果則中斷任務拋出TimeoutException異常。
  • join方法會拋出未檢查異常,與get()方法不同的是join()方法不允許被中斷。
// 可中斷,可設置超時時間
public T get() throws InterruptedException, ExecutionException {...}
public T get(long timeout, TimeUnit unit) throws InterruptedException, 
                ExecutionException, TimeoutException {...}
/**
* 不可中斷
*/
public T join() {...}

3.CompletionStage的方法使用說明

CompletionStage表示一個任務的執(zhí)行階段,每個任務都會返回一個CompletionStage對象,可以對多個CompletionStage對象進行串行、并行或者聚合的方式來進行下階段的操作,也就是說實現(xiàn)異步任務的回調功能。CompletionStage總共提供了38個方法來實現(xiàn)多個CompletionStage任務的各種操作, 接下來我們就針對這些方法分類來了解一下。

以下類型均有三種使用方式:

  • thenAccept:方法名不帶Async的使用主線程同步執(zhí)行回調函數(shù),不做異步處理
  • thenAcceptAsync:方法名帶Async,但是無executor參數(shù)的,使用默認線程池ForkJoinPool.commonPool異步執(zhí)行任務
  • thenAcceptAsync:方法名帶Async,有executor參數(shù)的,使用自定義線程池異步執(zhí)行任務

3.1 純消費類型

  • 依賴單個任務完成(thenAccept):由上一個CompletionStage任務執(zhí)行完成的結果傳遞到action進行回調處理,即僅僅消費了上一個CompletionStage任務的返回值,回調處理結果無返回值。
// 不使用線程池,僅依賴當前線程執(zhí)行,不做異步
public CompletionStage<Void> thenAccept(Consumer<? super T> action);
// 使用默認線程池ForkJoinPool.commonPool執(zhí)行任務
public CompletionStage<Void> thenAcceptAsync(Consumer<? super T> action);
// 使用自定義線程池執(zhí)行任務
public CompletionStage<Void> thenAcceptAsync(Consumer<? super T> action, Executor executor);

// ====================================demo華麗分割線============================================
CompletableFuture.supplyAsync(() -> "this is supplyAsync")
        .thenAcceptAsync((result) -> {
            log.info("{} thenAcceptAsync", result);
        }).join();
        
// 輸出結果:this is supplyAsync thenAcceptAsync

依賴兩個任務都完成(thenAcceptBoth):兩個CompletionStage任務并發(fā)執(zhí)行,必須都完成了才執(zhí)行action回調處理,即僅僅消費了兩個CompletionStage任務的返回值,回調處理結果無返回值。

/**
* 額外多了CompletionStage參數(shù)表示CompletionStage任務依賴的另一個CompletionStage任務
* action接收兩個參數(shù),分別表示兩個CompletionStage任務的返回值
*/
public <U> CompletionStage<Void> thenAcceptBoth(CompletionStage<? extends U> other, 
                            BiConsumer<? super T, ? super U> action);
// 原理同上,使用默認線程池執(zhí)行異步任務
public <U> CompletionStage<Void> thenAcceptBothAsync(CompletionStage<? extends U> other, 
                            BiConsumer<? super T, ? super U> action);
// 原理同上,使用自定義線程池執(zhí)行異步任務
public <U> CompletionStage<Void> thenAcceptBothAsync(CompletionStage<? extends U> other, 
                            BiConsumer<? super T, ? super U> action, Executor executor);

// ====================================demo華麗分割線============================================
CompletableFuture<String> cf311 = CompletableFuture.supplyAsync(() -> "this is supplyAsync cf311");
CompletableFuture<String> cf312 = CompletableFuture.supplyAsync(() -> "this is supplyAsync cf312");
cf311.thenAcceptBothAsync(cf312, (r1, r2) -> {
   log.info("{} and {}", r1, r2);
}).join();
// 輸出結果:this is supplyAsync cf311 and this is supplyAsync cf312

依賴兩個任務中的任何一個完成(acceptEither):兩個CompletionStage任務并發(fā)執(zhí)行,只要其中一個先完成了就攜帶返回值執(zhí)行action回調處理,即僅僅消費了優(yōu)先完成的CompletionStage任務的返回值,回調處理結果無返回值。

/**
* 類似thenAcceptBothAsync,只不過acceptEither只需兩個任務中的其中一個完成即可回調action
* action中的值為兩個任務中先執(zhí)行完任務的返回值
*/
public CompletionStage<Void> acceptEither(CompletionStage<? extends T> other,
                             Consumer<? super T> action);
public CompletionStage<Void> acceptEitherAsync(CompletionStage<? extends T> other,
                             Consumer<? super T> action);
public CompletionStage<Void> acceptEitherAsync(CompletionStage<? extends T> other,
                             Consumer<? super T> action, Executor executor);

// ====================================demo華麗分割線============================================
CompletableFuture<String> cf311 = CompletableFuture.supplyAsync(() -> "this is supplyAsync cf311");
CompletableFuture<String> cf312 = CompletableFuture.supplyAsync(() -> "this is supplyAsync cf312");
cf311.acceptEitherAsync(cf312, (r) -> {
    log.info(r); // 輸出結果:this is supplyAsync cf311或cf312
}).join();

3.2 有返回值類型

依賴單個任務完成(thenApply):由上一個CompletionStage任務執(zhí)行完成的結果傳遞到action進行回調處理,即不止消費了上一個CompletaionStage任務的返回值,同時回調處理結果也有返回值

public <U> CompletionStage<U> thenApply(Function<? super T,? extends U> fn);
public <U> CompletionStage<U> thenApplyAsync(Function<? super T,? extends U> fn);
public <U> CompletionStage<U> thenApplyAsync(Function<? super T,? extends U> fn, Executor executor);

// ====================================demo華麗分割線============================================
CompletableFuture<String> cf32 = CompletableFuture.supplyAsync(() -> "this is supplyAsync")
        .thenApplyAsync(result -> result + " and thenApplyAsync");
log.info(cf32.join());  // 輸出結果:this is supplyAsync and thenApplyAsync

依賴兩個任務都完成(thenCombine):兩個CompletionStage任務并發(fā)執(zhí)行,必須都完成了才執(zhí)行action回調處理,即不止消費了兩個CompletaionStage任務的返回值,同時回調處理結果也有返回值。

public <U,V> CompletionStage<V> thenCombine(CompletionStage<? extends U> other,
                             BiFunction<? super T,? super U,? extends V> fn);
public <U,V> CompletionStage<V> thenCombineAsync(CompletionStage<? extends U> other,
                             BiFunction<? super T,? super U,? extends V> fn);
public <U,V> CompletionStage<V> thenCombineAsync(CompletionStage<? extends U> other,
                             BiFunction<? super T,? super U,? extends V> fn, Executor executor);

// ====================================demo華麗分割線============================================
CompletableFuture<String> cf321 = CompletableFuture.supplyAsync(() -> "this is supplyAsync cf321");
CompletableFuture<String> cf322 = CompletableFuture.supplyAsync(() -> "this is supplyAsync cf322");
CompletableFuture<String> thenCombineFuture = cf321.thenCombineAsync(cf322, (r1, r2) -> {
    return r1 + " and " + r2;
});
log.info(thenCombineFuture.join());
// 輸出結果:this is supplyAsync cf321 and this is supplyAsync cf322

依賴兩個任務中的任何一個完成(applyToEither):兩個CompletionStage任務并發(fā)執(zhí)行,只要其中一個任務執(zhí)行完成就會action回調處理,即不止消費了優(yōu)先完成的CompletionStage的返回值,同時回調處理結果也有返回值。

// 原理同3.1的acceptEither,只不過applyToEither任務執(zhí)行完成會返回一個帶有返回值的CompletionStage
public <U> CompletionStage<U> applyToEither(CompletionStage<? extends T> other,
                             Function<? super T, U> fn);
public <U> CompletionStage<U> applyToEitherAsync(CompletionStage<? extends T> other,
                             Function<? super T, U> fn);
public <U> CompletionStage<U> applyToEitherAsync(CompletionStage<? extends T> other,
                             Function<? super T, U> fn, Executor executor);

// ====================================demo華麗分割線============================================

CompletableFuture<String> cf321 = CompletableFuture.supplyAsync(() -> "this is supplyAsync cf321");
CompletableFuture<String> cf322 = CompletableFuture.supplyAsync(() -> "this is supplyAsync cf322");
CompletableFuture<String> thenCombineFuture = cf321.applyToEitherAsync(cf322, (r) -> {
    return r;
});
log.info(thenCombineFuture.join());
// 輸出結果:this is supplyAsync cf321或cf322

3.3 不消費也不返回類型

依賴單個任務完成(thenRun):單個CompletionStage任務執(zhí)行完成回調action處理,即執(zhí)行action回調方法無參數(shù),回調處理結果也無返回值。

// 上一個CompletionStage任務執(zhí)行完成后直接回調action處理,無返回值
public CompletionStage<Void> thenRun(Runnable action);
// 同上,使用默認線程池執(zhí)行action處理
public CompletionStage<Void> thenRunAsync(Runnable action);
// 同上,使用自定義線程池執(zhí)行action處理
public CompletionStage<Void> thenRunAsync(Runnable action, Executor executor);

// ====================================demo華麗分割線============================================
CompletableFuture.runAsync(() -> {
    // TODO
}).thenRunAsync(() -> {
    log.info("this is thenRunAsync");  // 輸出結果:this is thenRunAsync
}).join();

依賴兩個任務都完成(runAfterBoth):兩個CompletionStage任務并發(fā)執(zhí)行,必須兩個任務都完成才執(zhí)行action回調處理,即執(zhí)行action回調方法無參數(shù),回調處理結果也無返回值。

// 原理同3.1的thenAcceptBoth,只不過runAfterBoth的action回調處理不接收參數(shù)且任務執(zhí)行完成無返回值
public CompletionStage<Void> runAfterBoth(CompletionStage<?> other, Runnable action);
// 同上,使用默認線程池執(zhí)行action處理
public CompletionStage<Void> runAfterBothAsync(CompletionStage<?> other, Runnable action);
// 同上,使用自定義線程池執(zhí)行action處理
public CompletionStage<Void> runAfterBothAsync(CompletionStage<?> other, Runnable action, Executor executor);

// ====================================demo華麗分割線============================================
CompletableFuture<String> cf331 = CompletableFuture.supplyAsync(() -> "this is supplyAsync cf331");
CompletableFuture<String> cf332 = CompletableFuture.supplyAsync(() -> "this is supplyAsync cf332");
cf331.runAfterBoth(cf332, () -> {
    log.info("this is runAfterBoth");
}).join();
// 輸出結果:this is runAfterBoth

依賴兩個任務中的任何一個完成(runAfterEither):兩個CompletionStage任務并發(fā)執(zhí)行,只需其中任何一個任務完成即可回調action處理,即執(zhí)行action回調方法無參數(shù),回調處理結果也無返回值。

public CompletionStage<Void> runAfterEither(CompletionStage<?> other, Runnable action);
public CompletionStage<Void> runAfterEitherAsync(CompletionStage<?> other, Runnable action);
public CompletionStage<Void> runAfterEitherAsync(CompletionStage<?> other, Runnable action, Executor executor);

// ====================================demo華麗分割線============================================
CompletableFuture<String> cf331 = CompletableFuture.supplyAsync(() -> "this is supplyAsync cf331");
CompletableFuture<String> cf332 = CompletableFuture.supplyAsync(() -> "this is supplyAsync cf332");
cf331.runAfterEitherAsync(cf332, () -> {
    log.info("this is runAfterEitherAsync");
}).join();
// 輸出結果:this is runAfterEitherAsync

3.4 組合類型

thenCompose:存在先后關系的兩個任務進行串行組合,由第一個CompletionStage任務執(zhí)行結果作為參數(shù)傳遞給第二個CompletionStage任務,最終返回第二個CompletionStage。

public <U> CompletionStage<U> thenCompose(Function<? super T, ? extends CompletionStage<U>> fn);
public <U> CompletionStage<U> thenComposeAsync(Function<? super T, ? extends CompletionStage<U>> fn);
public <U> CompletionStage<U> thenComposeAsync(Function<? super T, ? extends CompletionStage<U>> fn, Executor executor);

// ====================================demo華麗分割線============================================
CompletableFuture<String> supplyFuture = CompletableFuture.supplyAsync(() -> {
    return "this is supplyAsync";
});
CompletableFuture<String> thenComposeFuture = supplyFuture.thenComposeAsync((r) -> {
    return CompletableFuture.supplyAsync(() -> {
        return r + " and this is thenComposeAsync";
    });
});
log.info(thenComposeFuture.join());
// 輸出結果:this is supplyAsync and this is thenComposeAsync

3.5 任務事件類型

CompletionStage接口也支持類似我們常用的try-catch-finally中的finally的作用,無論這個任務的執(zhí)行結果是正常還是出現(xiàn)異常的情況,都必須要去執(zhí)行的一個代碼塊。在CompletionStage接口提供了以下兩種接口回調的形式(whenComplete、handle),并支持主線程同步執(zhí)行同時也支持使用默認線程池,或者使用自定義線程池去異步執(zhí)行最終的回調處理。例如我們一個事務操作,無論這段代碼執(zhí)行是否成功,我們都必須要去關閉事務。

任務完成事件(whenComplete):結果無返回值,若出現(xiàn)異常執(zhí)行完whenComplete回調處理完成后將中斷主線程的運行。

// 1.whenComplete回調函數(shù)中Throwable對象不對空代表出現(xiàn)異常,為空則表示無異常
public CompletionStage<T> whenComplete(BiConsumer<? super T, ? super Throwable> action);
public CompletionStage<T> whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action);
public CompletionStage<T> whenCompleteAsync(BiConsumer<? super T, ? super Throwable> action, Executor executor);

// ====================================demo華麗分割線============================================
CompletableFuture<String> whenCompleteFufute = CompletableFuture.supplyAsync(() -> {
    int a = 0;
    int b = 100 / a;
    return "this is supplyAsync normal";
}).whenCompleteAsync((r, th) -> {
    if (th != null) {
        log.error("this is whenCompleteAsync error");
    }
    else {
        log.info("this is whenCompleteAsync success");
    }
});
log.info(whenCompleteFufute.join());  // 輸出結果:this is whenCompleteAsync error

任務完成回調事件(handle):結果有返回值,若出現(xiàn)異常執(zhí)行完handle回調處理完成后將繼續(xù)執(zhí)行主線程的后續(xù)操作,不中斷主線程運行。

// 2.handle回調函數(shù)中Throwable對象不對空代表出現(xiàn)異常,為空則表示無異常
public <U> CompletionStage<U> handle(BiFunction<? super T, Throwable, ? extends U> fn);
public <U> CompletionStage<U> handleAsync(BiFunction<? super T, Throwable, ? extends U> fn);
public <U> CompletionStage<U> handleAsync(BiFunction<? super T, Throwable, ? extends U> fn, Executor executor);

// ====================================demo華麗分割線============================================
CompletableFuture<String> whenCompleteFufute = CompletableFuture.supplyAsync(() -> {
    int a = 0;
    int b = 100 / a;
    return "this is supplyAsync normal";
}).handleAsync((r, th) -> {
    if (th != null) {
        return "this is handleAsync error";
    }
    else {
        return "this is handleAsync success";
    }
});
log.info(whenCompleteFufute.join());
// 輸出結果:this is handleAsync error
log.info("main thread is running");
// 輸出結果:main thread is running

4.CompletionStage異常處理方法

exceptionally:只要是個程序,就會有異常出現(xiàn)的情況,例如一個CompletionStage任務,如果執(zhí)行過程中出現(xiàn)異常,我們?yōu)榱吮WC異常情況下程序能夠正常處理業(yè)務邏輯,那么在這里我們就可以使用exceptionally進行異常回調處理。當CompletionStage任務出現(xiàn)異常時就會觸發(fā)回調exceptionally,否則CompletionStage任務正常執(zhí)行業(yè)務不進行異?;卣{處理。

public CompletionStage<T> exceptionally(Function<Throwable, ? extends T> fn);

// ====================================demo華麗分割線============================================
CompletableFuture<String> exceptionallyFuture = CompletableFuture.supplyAsync(() -> {
    int a = 0;
    int b = 10 / a;  // 除數(shù)為0將拋異常
    return "this is supplyAsync normal";
}).exceptionally(th -> {
    log.error("exception:{}", th.getMessage());
    return "this is exceptionally";
});
log.info(exceptionallyFuture.join());  // 輸出結果:this is exceptionally

:以下這兩種情況可能大家在實際開發(fā)過程中會比較少見,但還是得在這里做個提醒,以免到最后準備不充分出現(xiàn)設計上的缺陷。

  • 當whenCompleteAsync與exceptionally同時使用時,若出現(xiàn)異常情況,由于exceptionally有返回值,所以優(yōu)先執(zhí)行whenCompleteAsync,后執(zhí)行exceptionally。
  • 當handleAsync與exceptionally同時出現(xiàn)時,由于handleAsync已經(jīng)包含了exceptionally的所有操作,即handleAsync回調有返回值,且有Throwable異常對象能夠進行異常處理,所以這兩者同時出現(xiàn)時exceptionally將失效。

5.方法類型總結

根據(jù)以上的方法我們可以總結出這些任務其實就分為三大類,相當于通過CompletionStage的回調機制來實現(xiàn)多個任務串、多個任務并行、多個任務聚合的操作,因此CompletableFuture對于異步任務的處理提供了更加強大的編程模型。所以說java8提供的CompletableFuture類相對原來的Future接口來說提供了一些鏈式的編程,省去了我們很多異步任務回調操作復雜的步驟,讓我們這些碼農(nóng)們能夠有更高的效率輸出產(chǎn)品。

到此這篇關于Java8并發(fā)新特性CompletableFuture的文章就介紹到這了,更多相關Java8 CompletableFuture內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Java操作excel的三種常見方法實例

    Java操作excel的三種常見方法實例

    這篇文章主要給大家介紹了關于Java操作excel的三種常見方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-04-04
  • Spring需要三個級別緩存解決循環(huán)依賴原理解析

    Spring需要三個級別緩存解決循環(huán)依賴原理解析

    這篇文章主要為大家介紹了Spring需要三個級別緩存解決循環(huán)依賴原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-02-02
  • 詳細了解JAVA NIO之Buffer(緩沖區(qū))

    詳細了解JAVA NIO之Buffer(緩沖區(qū))

    這篇文章主要介紹了JAVA NIO之Buffer(緩沖區(qū))的相關資料,文中講解非常細致,幫助大家更好的學習JAVA NIO,感興趣的朋友可以了解下
    2020-07-07
  • Java中深拷貝和淺拷貝的區(qū)別解析

    Java中深拷貝和淺拷貝的區(qū)別解析

    這篇文章主要介紹了Java中深拷貝和淺拷貝的區(qū)別解析,淺拷貝是源對象和拷貝對象的存放地址不同,但被復制的源對象的引用類型屬性存放的地址仍然和源對象的引用類型屬性相同,修改引用類型屬性的屬性會影響相互影響,需要的朋友可以參考下
    2024-01-01
  • 詳解SpringIOC容器相關知識

    詳解SpringIOC容器相關知識

    這篇文章主要記錄自己在狂神說java中的學習情況,文章里有自己學習的理解和擴展,新手難免有理解偏差或者錯誤,懇請大佬指正下,需要的朋友可以參考下
    2021-05-05
  • Spring Boot集成MinIO對象存儲服務器操作步驟

    Spring Boot集成MinIO對象存儲服務器操作步驟

    通過Spring Boot集成MinIO,你可以在應用中方便地進行文件的存儲和管理,本文給大家分享Spring Boot集成MinIO對象存儲服務器詳細操作步驟,感興趣的朋友一起看看吧
    2024-01-01
  • springmvc處理模型數(shù)據(jù)Map過程解析

    springmvc處理模型數(shù)據(jù)Map過程解析

    這篇文章主要介紹了springmvc處理模型數(shù)據(jù)Map過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-01-01
  • 詳解在Spring3中使用注解(@Scheduled)創(chuàng)建計劃任務

    詳解在Spring3中使用注解(@Scheduled)創(chuàng)建計劃任務

    本篇文章主要介紹了詳解在Spring3中使用注解(@Scheduled)創(chuàng)建計劃任務,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2017-03-03
  • SpringMvc后臺接收json數(shù)據(jù)中文亂碼問題詳解

    SpringMvc后臺接收json數(shù)據(jù)中文亂碼問題詳解

    這篇文章主要介紹了SpringMvc后臺接收json數(shù)據(jù)中文亂碼問題詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-09-09
  • Java中實例初始化和靜態(tài)初始化的過程詳解

    Java中實例初始化和靜態(tài)初始化的過程詳解

    Java代碼初始化塊是Java語言中的一個非常重要的概念。初始化塊負責在創(chuàng)建對象時進行一些必要的操作,例如設置對象的初始狀態(tài)、初始化成員變量等。初始化塊被分為實例初始化塊和靜態(tài)初始化塊兩種類型。本文詳細介紹了初始化的過程,需要的朋友可以參考下
    2023-05-05

最新評論

柯坪县| 望奎县| 深圳市| 普陀区| 筠连县| 靖江市| 镶黄旗| 东乌| 元朗区| 铜川市| 汨罗市| 玉龙| 临泉县| 高雄县| 肥乡县| 芜湖县| 深泽县| 万载县| 随州市| 宾阳县| 临潭县| 中卫市| 古蔺县| 高碑店市| 慈溪市| 汤阴县| 马公市| 托里县| 文成县| 罗源县| 肇东市| 大冶市| 九龙坡区| 苏尼特左旗| 泰宁县| 普兰店市| 扶沟县| 清水县| 雷州市| 通河县| 措勤县|