Artyom Gornostayev
03/27/2024, 10:26 AMProduct
with a log of attributes (nullable and non-nullable).
Compiler generates byte code where it creates constructor similar to this:
Product.decompiled.java
...
// $FF: synthetic method
public Product(String var1, ..., int var40, int var41, DefaultConstructorMarker var42) {
if ((var40 & 1073741824) != 0) {
var31 = null;
}
if ((var40 & Integer.MIN_VALUE) != 0) {
var32 = null;
}
if ((var41 & 1) != 0) {
var33 = null;
}
if ((var41 & 2) != 0) {
var34 = null;
}
...
this(var1, ... var39);
}
There are two attributes var40
and var41
which (as I understood) rules nullability...
What is a logic behind this? Why compiler splits nullable fields into two groups?
Thanks a lot.dmitriy.novozhilov
03/27/2024, 10:36 AMvar40
and var41
are bit masks which determine what values were passed explicitly and what should be taken from default
It seems like all your defaults are null
, so you can see varXX = null
Check the other case:
data class Some(val x: String = "a", val y: String? = null)
// decompiled
public Some(String var1, String var2, int var3, DefaultConstructorMarker var4) {
if ((var3 & 1) != 0) {
var1 = "a";
}
if ((var3 & 2) != 0) {
var2 = null;
}
this(var1, var2);
}
Note that in this example there is only one int
parameter, because Some
constructor has less than 32 parameters, and it's enough just one int
to cover all casesArtyom Gornostayev
03/27/2024, 10:42 AM