I'm looking at some decompiled code and seeing .getClass();
, i.e. nothing being done with its return value.
public String forLocale(Locale locale, String keyword) {
Stream var10000 = getLocaleMappingList(locale, this.getSupportedLocales());
Map var10001 = this.translations;
var10001.getClass();
Map<String, String> translation = (Map)var10000.map(var10001::get).filter((m) -> {
return m.containsKey(keyword);
}).findFirst().orElse(this.translations.get(FALLBACK));
Preconditions.checkState(translation.containsKey(keyword), keyword + " is not a valid translation key");
return (String)translation.get(keyword);
}
What is that for? Was it in the original code like that? (So far I haven't seen an instance of decompiled code not matching up at least line-wise to source code.)
It kind of looks like an assertion, but then what is achieved by doing that as opposed to letting things go wrong at var10001::get
? Or is it more about performance?
Update
Here's the bytecode. Cool thing to learn how to do!
// access flags 0x1
public forLocale(Ljava/util/Locale;Ljava/lang/String;)Ljava/lang/String;
L0
LINENUMBER 184 L0
ALOAD 1
ALOAD 0
INVOKEVIRTUAL com/spotify/i18n/Translations.getSupportedLocales ()Ljava/util/Set;
INVOKESTATIC com/spotify/i18n/Translations.getLocaleMappingList (Ljava/util/Locale;Ljava/util/Collection;)Ljava/util/stream/Stream;
ALOAD 0
GETFIELD com/spotify/i18n/Translations.translations : Ljava/util/Map;
DUP
INVOKEVIRTUAL java/lang/Object.getClass ()Ljava/lang/Class;
POP
INVOKEDYNAMIC apply(Ljava/util/Map;)Ljava/util/function/Function; [
// handle kind 0x6 : 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;
// arguments:
(Ljava/lang/Object;)Ljava/lang/Object;,
// handle kind 0x9 : INVOKEINTERFACE
java/util/Map.get(Ljava/lang/Object;)Ljava/lang/Object; itf,
(Ljava/util/Locale;)Ljava/util/Map;
]
This looks like decompiled code, and my guess is that the decompiler hasn't generated Java code that is equivalent to the original source code.
The literal meaning of
var10001.getClass();
is to return the Class
object for the type of the object that var10001
refers to. But the value that is returned appears to be discarded, so the call (apparently) doesn't achieve anything. Hence, my tentative conclusion that the decompiler has stuffed up.
You may need to read the (disassembled) bytecodes directly to discern what they are actually doing. (Or you could try a different decompiler.)
UPDATE
It is plausible that getClass()
is called solely for the side-effect of checking for null
. (I've never seen that idiom ... but it would work.) I wouldn't expect it to make the code faster, but it would make it more compact.
However, if this is being done in the (original) source code, it would appear to be unnecessary. A couple of lines later, the code takes var10001::get
and passes it as an argument in a Stream.map
call. I'm pretty sure that that evaluating var10001::get
will entail checking that var10001
is not null
.