fb-contrib
fb-contrib copied to clipboard
PRMC_POSSIBLY_REDUNDANT_METHOD_CALLS false positive
return dbMapper.batchLoad(contactsIdsOnly).values().stream().
flatMap(Collection::stream).
filter(Contact.class::isInstance).
map(Contact.class::cast). // PRMC_POSSIBLY_REDUNDANT_METHOD_CALLS here
collect(toList());
javac 10.0.1 spotbugs 3.1.10 fb-contrib 7.4.3.sb MacOS, doesn't seem to happen in our Linux CI builds
mind running javap -v -private YourClass
and dumping the byte code for at least this sequence of statements?
Same issue in SonarQube Community Edition Version 8.9.7 (build 52159), which implies Findbugs Plugin v4.0.6, which implies fb-contrib v7.4.7 (sb-contrib)
and dumping the byte code for at least this sequence of statements?
Java code
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class TestClass {
public Set<String> test1(List<Object> list) {
return list.stream()
.filter(String.class::isInstance)
.map(String.class::cast)
.collect(Collectors.toSet());
}
public Set<String> test2(List<Object> list) {
Class<String> StringClass = String.class;
return list.stream()
.filter(StringClass::isInstance)
.map(StringClass::cast)
.collect(Collectors.toSet());
}
}
Dump
$ javap -v -private TestClass.class
Classfile /home/pbludov/src/tmp/TestClass.class
Last modified 6 мая 2022 г.; size 2162 bytes
SHA-256 checksum bd6fdc72267018c66ad0983cacb8a8f45d53fde0a2c6238ea500db7f444b579f
Compiled from "TestClass.java"
public class TestClass
minor version: 0
major version: 62
flags: (0x0021) ACC_PUBLIC, ACC_SUPER
this_class: #51 // TestClass
super_class: #2 // java/lang/Object
interfaces: 0, fields: 0, methods: 3, attributes: 3
Constant pool:
#1 = Methodref #2.#3 // java/lang/Object."<init>":()V
#2 = Class #4 // java/lang/Object
#3 = NameAndType #5:#6 // "<init>":()V
#4 = Utf8 java/lang/Object
#5 = Utf8 <init>
#6 = Utf8 ()V
#7 = InterfaceMethodref #8.#9 // java/util/List.stream:()Ljava/util/stream/Stream;
#8 = Class #10 // java/util/List
#9 = NameAndType #11:#12 // stream:()Ljava/util/stream/Stream;
#10 = Utf8 java/util/List
#11 = Utf8 stream
#12 = Utf8 ()Ljava/util/stream/Stream;
#13 = Class #14 // java/lang/String
#14 = Utf8 java/lang/String
#15 = Methodref #16.#17 // java/util/Objects.requireNonNull:(Ljava/lang/Object;)Ljava/lang/Object;
#16 = Class #18 // java/util/Objects
#17 = NameAndType #19:#20 // requireNonNull:(Ljava/lang/Object;)Ljava/lang/Object;
#18 = Utf8 java/util/Objects
#19 = Utf8 requireNonNull
#20 = Utf8 (Ljava/lang/Object;)Ljava/lang/Object;
#21 = InvokeDynamic #0:#22 // #0:test:(Ljava/lang/Class;)Ljava/util/function/Predicate;
#22 = NameAndType #23:#24 // test:(Ljava/lang/Class;)Ljava/util/function/Predicate;
#23 = Utf8 test
#24 = Utf8 (Ljava/lang/Class;)Ljava/util/function/Predicate;
#25 = InterfaceMethodref #26.#27 // java/util/stream/Stream.filter:(Ljava/util/function/Predicate;)Ljava/util/stream/Stream;
#26 = Class #28 // java/util/stream/Stream
#27 = NameAndType #29:#30 // filter:(Ljava/util/function/Predicate;)Ljava/util/stream/Stream;
#28 = Utf8 java/util/stream/Stream
#29 = Utf8 filter
#30 = Utf8 (Ljava/util/function/Predicate;)Ljava/util/stream/Stream;
#31 = InvokeDynamic #1:#32 // #1:apply:(Ljava/lang/Class;)Ljava/util/function/Function;
#32 = NameAndType #33:#34 // apply:(Ljava/lang/Class;)Ljava/util/function/Function;
#33 = Utf8 apply
#34 = Utf8 (Ljava/lang/Class;)Ljava/util/function/Function;
#35 = InterfaceMethodref #26.#36 // java/util/stream/Stream.map:(Ljava/util/function/Function;)Ljava/util/stream/Stream;
#36 = NameAndType #37:#38 // map:(Ljava/util/function/Function;)Ljava/util/stream/Stream;
#37 = Utf8 map
#38 = Utf8 (Ljava/util/function/Function;)Ljava/util/stream/Stream;
#39 = Methodref #40.#41 // java/util/stream/Collectors.toSet:()Ljava/util/stream/Collector;
#40 = Class #42 // java/util/stream/Collectors
#41 = NameAndType #43:#44 // toSet:()Ljava/util/stream/Collector;
#42 = Utf8 java/util/stream/Collectors
#43 = Utf8 toSet
#44 = Utf8 ()Ljava/util/stream/Collector;
#45 = InterfaceMethodref #26.#46 // java/util/stream/Stream.collect:(Ljava/util/stream/Collector;)Ljava/lang/Object;
#46 = NameAndType #47:#48 // collect:(Ljava/util/stream/Collector;)Ljava/lang/Object;
#47 = Utf8 collect
#48 = Utf8 (Ljava/util/stream/Collector;)Ljava/lang/Object;
#49 = Class #50 // java/util/Set
#50 = Utf8 java/util/Set
#51 = Class #52 // TestClass
#52 = Utf8 TestClass
#53 = Utf8 Code
#54 = Utf8 LineNumberTable
#55 = Utf8 LocalVariableTable
#56 = Utf8 this
#57 = Utf8 LTestClass;
#58 = Utf8 test1
#59 = Utf8 (Ljava/util/List;)Ljava/util/Set;
#60 = Utf8 list
#61 = Utf8 Ljava/util/List;
#62 = Utf8 LocalVariableTypeTable
#63 = Utf8 Ljava/util/List<Ljava/lang/Object;>;
#64 = Utf8 Signature
#65 = Utf8 (Ljava/util/List<Ljava/lang/Object;>;)Ljava/util/Set<Ljava/lang/String;>;
#66 = Utf8 test2
#67 = Utf8 StringClass
#68 = Utf8 Ljava/lang/Class;
#69 = Utf8 Ljava/lang/Class<Ljava/lang/String;>;
#70 = Utf8 SourceFile
#71 = Utf8 TestClass.java
#72 = Utf8 BootstrapMethods
#73 = MethodHandle 6:#74 // REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
#74 = Methodref #75.#76 // java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
#75 = Class #77 // java/lang/invoke/LambdaMetafactory
#76 = NameAndType #78:#79 // metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
#77 = Utf8 java/lang/invoke/LambdaMetafactory
#78 = Utf8 metafactory
#79 = Utf8 (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
#80 = MethodType #81 // (Ljava/lang/Object;)Z
#81 = Utf8 (Ljava/lang/Object;)Z
#82 = MethodHandle 5:#83 // REF_invokeVirtual java/lang/Class.isInstance:(Ljava/lang/Object;)Z
#83 = Methodref #84.#85 // java/lang/Class.isInstance:(Ljava/lang/Object;)Z
#84 = Class #86 // java/lang/Class
#85 = NameAndType #87:#81 // isInstance:(Ljava/lang/Object;)Z
#86 = Utf8 java/lang/Class
#87 = Utf8 isInstance
#88 = MethodType #20 // (Ljava/lang/Object;)Ljava/lang/Object;
#89 = MethodHandle 5:#90 // REF_invokeVirtual java/lang/Class.cast:(Ljava/lang/Object;)Ljava/lang/Object;
#90 = Methodref #84.#91 // java/lang/Class.cast:(Ljava/lang/Object;)Ljava/lang/Object;
#91 = NameAndType #92:#20 // cast:(Ljava/lang/Object;)Ljava/lang/Object;
#92 = Utf8 cast
#93 = MethodType #94 // (Ljava/lang/Object;)Ljava/lang/String;
#94 = Utf8 (Ljava/lang/Object;)Ljava/lang/String;
#95 = Utf8 InnerClasses
#96 = Class #97 // java/lang/invoke/MethodHandles$Lookup
#97 = Utf8 java/lang/invoke/MethodHandles$Lookup
#98 = Class #99 // java/lang/invoke/MethodHandles
#99 = Utf8 java/lang/invoke/MethodHandles
#100 = Utf8 Lookup
{
public TestClass();
descriptor: ()V
flags: (0x0001) ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 5: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this LTestClass;
public java.util.Set<java.lang.String> test1(java.util.List<java.lang.Object>);
descriptor: (Ljava/util/List;)Ljava/util/Set;
flags: (0x0001) ACC_PUBLIC
Code:
stack=3, locals=2, args_size=2
0: aload_1
1: invokeinterface #7, 1 // InterfaceMethod java/util/List.stream:()Ljava/util/stream/Stream;
6: ldc #13 // class java/lang/String
8: dup
9: invokestatic #15 // Method java/util/Objects.requireNonNull:(Ljava/lang/Object;)Ljava/lang/Object;
12: pop
13: invokedynamic #21, 0 // InvokeDynamic #0:test:(Ljava/lang/Class;)Ljava/util/function/Predicate;
18: invokeinterface #25, 2 // InterfaceMethod java/util/stream/Stream.filter:(Ljava/util/function/Predicate;)Ljava/util/stream/Stream;
23: ldc #13 // class java/lang/String
25: dup
26: invokestatic #15 // Method java/util/Objects.requireNonNull:(Ljava/lang/Object;)Ljava/lang/Object;
29: pop
30: invokedynamic #31, 0 // InvokeDynamic #1:apply:(Ljava/lang/Class;)Ljava/util/function/Function;
35: invokeinterface #35, 2 // InterfaceMethod java/util/stream/Stream.map:(Ljava/util/function/Function;)Ljava/util/stream/Stream;
40: invokestatic #39 // Method java/util/stream/Collectors.toSet:()Ljava/util/stream/Collector;
43: invokeinterface #45, 2 // InterfaceMethod java/util/stream/Stream.collect:(Ljava/util/stream/Collector;)Ljava/lang/Object;
48: checkcast #49 // class java/util/Set
51: areturn
LineNumberTable:
line 8: 0
line 9: 9
line 10: 26
line 11: 40
line 8: 51
LocalVariableTable:
Start Length Slot Name Signature
0 52 0 this LTestClass;
0 52 1 list Ljava/util/List;
LocalVariableTypeTable:
Start Length Slot Name Signature
0 52 1 list Ljava/util/List<Ljava/lang/Object;>;
Signature: #65 // (Ljava/util/List<Ljava/lang/Object;>;)Ljava/util/Set<Ljava/lang/String;>;
public java.util.Set<java.lang.String> test2(java.util.List<java.lang.Object>);
descriptor: (Ljava/util/List;)Ljava/util/Set;
flags: (0x0001) ACC_PUBLIC
Code:
stack=3, locals=3, args_size=2
0: ldc #13 // class java/lang/String
2: astore_2
3: aload_1
4: invokeinterface #7, 1 // InterfaceMethod java/util/List.stream:()Ljava/util/stream/Stream;
9: aload_2
10: dup
11: invokestatic #15 // Method java/util/Objects.requireNonNull:(Ljava/lang/Object;)Ljava/lang/Object;
14: pop
15: invokedynamic #21, 0 // InvokeDynamic #0:test:(Ljava/lang/Class;)Ljava/util/function/Predicate;
20: invokeinterface #25, 2 // InterfaceMethod java/util/stream/Stream.filter:(Ljava/util/function/Predicate;)Ljava/util/stream/Stream;
25: aload_2
26: dup
27: invokestatic #15 // Method java/util/Objects.requireNonNull:(Ljava/lang/Object;)Ljava/lang/Object;
30: pop
31: invokedynamic #31, 0 // InvokeDynamic #1:apply:(Ljava/lang/Class;)Ljava/util/function/Function;
36: invokeinterface #35, 2 // InterfaceMethod java/util/stream/Stream.map:(Ljava/util/function/Function;)Ljava/util/stream/Stream;
41: invokestatic #39 // Method java/util/stream/Collectors.toSet:()Ljava/util/stream/Collector;
44: invokeinterface #45, 2 // InterfaceMethod java/util/stream/Stream.collect:(Ljava/util/stream/Collector;)Ljava/lang/Object;
49: checkcast #49 // class java/util/Set
52: areturn
LineNumberTable:
line 16: 0
line 17: 3
line 18: 11
line 19: 27
line 20: 41
line 17: 52
LocalVariableTable:
Start Length Slot Name Signature
0 53 0 this LTestClass;
0 53 1 list Ljava/util/List;
3 50 2 StringClass Ljava/lang/Class;
LocalVariableTypeTable:
Start Length Slot Name Signature
0 53 1 list Ljava/util/List<Ljava/lang/Object;>;
3 50 2 StringClass Ljava/lang/Class<Ljava/lang/String;>;
Signature: #65 // (Ljava/util/List<Ljava/lang/Object;>;)Ljava/util/Set<Ljava/lang/String;>;
}
SourceFile: "TestClass.java"
BootstrapMethods:
0: #73 REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
Method arguments:
#80 (Ljava/lang/Object;)Z
#82 REF_invokeVirtual java/lang/Class.isInstance:(Ljava/lang/Object;)Z
#80 (Ljava/lang/Object;)Z
1: #73 REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
Method arguments:
#88 (Ljava/lang/Object;)Ljava/lang/Object;
#89 REF_invokeVirtual java/lang/Class.cast:(Ljava/lang/Object;)Ljava/lang/Object;
#93 (Ljava/lang/Object;)Ljava/lang/String;
InnerClasses:
public static final #100= #96 of #98; // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles