Pertimbangkan contoh Kotlin minimal berikut:
fun <U> someWrapper(supplier: () -> U): () -> (U) {
return { supplier() }
}
fun foo(taskExecutor: TaskExecutor): Int {
val future = CompletableFuture.supplyAsync(someWrapper {
42
}, taskExecutor::execute)
return future.join()
}
@Test
public void shouldFoo() {
assertThat(foo(), is(42));
}
Saya memiliki aturan cakupan cabang di Jacoco, yang gagal untuk kode di atas, mengatakan 1 dari 2 cabang tidak tercakup di someWrapper
telepon. Sayangnya, ini bukan pilihan bagi saya untuk mengecualikan semua kelas dari yang someWrapper
dipanggil.
Melihat kode Java yang didekompilasi:
public final int foo(TaskExecutor taskExecutor) {
Object var10000 = WrappersKt.someWrapper((Function0)null.INSTANCE);
if (var10000 != null) {
Object var2 = var10000;
var10000 = new Foo$sam$java_util_function_Supplier$0((Function0)var2);
}
Supplier var3 = (Supplier)var10000;
Function1 var4 = (Function1)(new Function1(this.taskExecutor) {
// $FF: synthetic method
// $FF: bridge method
public Object invoke(Object var1) {
this.invoke((Runnable)var1);
return Unit.INSTANCE;
}
public final void invoke(Runnable p1) {
((TaskExecutor)this.receiver).execute(p1);
}
public final KDeclarationContainer getOwner() {
return Reflection.getOrCreateKotlinClass(TaskExecutor.class);
}
public final String getName() {
return "execute";
}
public final String getSignature() {
return "execute(Ljava/lang/Runnable;)V";
}
});
CompletableFuture future = CompletableFuture.supplyAsync(var3, (Executor)(new Foo$sam$java_util_concurrent_Executor$0(var4)));
var10000 = future.join();
Intrinsics.checkExpressionValueIsNotNull(var10000, "future.join()");
return ((Number)var10000).intValue();
}
Saya pikir, masalahnya adalah if (var10000 != null)
cabang, yang bahkan ditandai oleh IDE menjadi tidak perlu (selalu benar).
Apakah mungkin untuk menyesuaikan kode sedemikian sehingga memungkinkan untuk mencakup semua cabang, mis. dengan memastikan kompiler tidak menghasilkan cek nol tambahan? Saya dapat mengubah kode keduanya foo(..)
dan someWrapper(..)
selama saya dapat menyediakan lambda yang didekorasi.
Saya menggunakan Kotlin 1.3.50 dan Jacoco 0.8.4.
EDIT.
Satu solusi yang jelas adalah mengekstraksi supplyAsync(someWrapper { ... })
ke beberapa kelas utilitas dan mengecualikan kelas itu saja, yaitu .:
fun <U> supplyAsync(supplier: () -> U, executor: TaskExecutor): CompletableFuture<U> {
return CompletableFuture.supplyAsync(someWrapper { supplier() }, executor::execute)
}
Ini akan cukup baik bagi saya, meskipun saya masih penasaran mengapa cabang ditambahkan oleh Kotlin, di mana tidak perlu ada cabang.
Type inference failed
ketika mencoba membuat kompilasi kode sampel Anda. Akan lebih bagus jika Anda bisa memberikan kode sampel yang berfungsi di luar kotak! Misalnya,taskExecutor
dancontroller
tidak diketahui.Jawaban:
Jika nilai kembali
someWrapper
hanya dimaksudkan untuk digunakan sebagai contohSupplier
, maka Anda dapat menghapus cek nol yang tidak perlu dengan menggunakan secara eksplisitSupplier
sebagai jenis pengembalian.sumber