Really excited about using `data object` for `toSt...
# language-evolution
e
Really excited about using
data object
for
toString
, however the old Android engineer in me is worried about the
equals
and
hashcode
functions being generated to handle what seems like a very niche edge case. Isn't that a waste of space (especially in large projects with lots of
data objects
)?
y
Using a
data object
already means that you're generating a class, so it's not really that significant. Also, I believe R8 handles a lot of inlining and stuff of `object`s in general (because it optimises for them specifically), and so it's very likely that, as long as you have only used the
data object
as a namespace, that it will simply optimize it out completely
j
Plus the destructuring components too. The thought crosses my mind occasionally as well. 🤖
Often it's just the
copy()
function I need.
y
I guess theoretically Kotlin could've had an intermediate `abstract class DataObject { override fun equals(other: Any?) = javaClass == other.javaClass }`and then had every data object implement it. I think it would've been a tiny bit less performant than the
instanceOf
that happens in the current impl
Often it's just the
copy()
function I need.
If you don't use them, R8 will optimize them out. That's why JVM libraries can have as many convenience methods as they want really.
d
If someone's using
data object
, it's probably because they're using the object as an actual object in a class hierarchy, so the object itself would not be eliminated. (Otherwise, why need
toString
in the first place?) When I decompile the data object, I get this:
Copy code
public final class DataObjectExample {
   @NotNull
   public static final DataObjectExample INSTANCE;

   private DataObjectExample() {
   }

   static {
      DataObjectExample var0 = new DataObjectExample();
      INSTANCE = var0;
   }

   @NotNull
   public String toString() {
      return "DataObjectExample";
   }

   public int hashCode() {
      return -370675483;
   }

   public boolean equals(@Nullable Object var1) {
      if (this != var1) {
         if (!(var1 instanceof DataObjectExample)) {
            return false;
         }

         DataObjectExample var2 = (DataObjectExample)var1;
      }

      return true;
   }
}
The class has a private constructor, so in theory the
hashCode
and
equals
methods don't actually need to exist (and the
equals
method is much longer than it needs to be while
hashCode
is just fine). As also an Android engineer, I would prefer to have the ability to opt out of such methods (and even such methods for
data class
where I only need one or two of the three methods, or more awkwardly, only really need the
equals
method for test cases). And while the
copy
and
componentX
methods can be eliminated easily by R8 for lack of use,
equals
and
hashCode
would be much more difficult to remove, if not impossible, if the object is still used.
m
equals
and
hashCode
would be much more difficult to remove, if not impossible, if the object is still used.
+1. Same for
toString
facebook even made a compiler plugin to remove them: https://github.com/facebookincubator/dataclassgenerate