Hi guys. I was told in one of my PR to try not use...
# android
n
Hi guys. I was told in one of my PR to try not use
lateinit
when defining variables due to the fact that it is only makes sense when using Java interop. Is there any other specific reason to not use
lateinit
?
mind blown 3
a
What does it mean “only makes sense when using Java interop” . I specifically thought it was to get around androids lifecycles or frameworks that require non constructor initialization
d
only makes sense when using Java interop
I don't think this is true at all. As @agrosner, it is for what the keyword says is "late init" when a variable is not suppose to be nullable but will be initialised at a later stage, e.g because of android's lifecycle.
👍 1
💯 1
d
lateinit
easily leads to exceptions and crashes, which is why better to avoid it
👎🏼 1
👎 3
👍 1
a
You can’t avoid it in Android development. Unless you make all things nullable..you can check if it is initialized as a last resort. Also if you make them all nullable you hide actual bugs in code rather than crashing early
💯 2
d
Just like double bang, lateinit is a keyword to be used with caution. You are basically saying "I promise that I will init this value at a later stage before using it." It is basically the same as using null and
!!
everywhere.
👍 1
a
Right but you can’t assign null to it, and typically don’t initialize it more than once
plus1 2
g
Yes, do not initialize it multiple times, until you eventually do by accident
😅 2
😂 1
or start using ::isInitialized Lateinit is really helpful only for very specific cases as Android Activity lifecycle (and similar cases from some JVM frameworks, when you do not control class creation), but even there it could be avoided in many cases and should be avoided because it's ugly and less safe
1
I don't know context of changes in you PR but I really would like to see a valid use case for lateinit outside of specific things like DI to classes, creation of which you do not own
h
lateinit can lead to crash in case your logic for to initialize this value. hope answer your question
👎 1
n
Ok so my use case is this. Please tell me if there's a workaround. I have a data class
Test
with 3 variables in it a,b and c. If I have 2 objects of Test class then they can be equal if variable a and b of both objects are equal but variable c can have any value. To achieve this I went with this option. I made a and b variable as constructor parameter but made c variable as lateinit var. I know I can override equals and hascode method to achieve this but is there any other way?
d
I'm not sure of the whole context around your usecase, but generally speaking you don't want
var
or
lateinit
in a
data class
. A
data class
should, as the name infer, contain data. Imo it should only contain
val
and possibly member functions to derive some extra data out from those
val
's. Since the context of your problem is not clear there is no one solution, it could be many options depending on the case: • Remove
c
from
Test
if it is not data/state. • Consider restructuring
Test
in to a sealed structure if
c
only exists in some cases. • Implement another function instead of using equals and hashcode.
👎 1
👍 1
👍🏼 1
g
It looks very messy to be honest, could you show an example of code in kotlin playground But from you exaplanation, I also agree with David, look that you need restructure it
n
Thanks for the feedback @David and from your options can you please elaborate on 3rd point as other points does apply since the value of
c
will always be present and is required in all objects created.
👍 1
d
No worries, I'd still like just clarify that best practice is for you to avoid using
var
&
lateinit
in any
data class
though. Then you still can have a custom compare method or
Comparator
to compare the two classes using only some of the properties.
👍 1
Good luck with your issue.