Kotlin leaking this in constructor

Issue

I have an abstract class that implements DefaultLifecycleObserver . I’d like to call lifecycle.addObserver(this) from the init block, but it says «Leaking ‘this’ in constructor of non-final class MyAbstractClass».

abstract class MyAbstractClass(protected val activity: AppCompatActivity) : DefaultLifecycleObserver < init < activity.lifecycle.addObserver(this) >. . . > 

I can move this line of code to the init block of each final class that extends this abstract class, but I don’t like the idea, especially because I want to guarantee that each new class that will extend MyAbstractClass in the future will call it as well. Is there a better place to call this without creating a leak?

Solution

I suppose you could post your call so it only happens after the object is fully instantiated:

abstract class MyAbstractClass(protected val activity: AppCompatActivity) : DefaultLifecycleObserver < init < Handler(Looper.getMainLooper()).post < activity.lifecycle.addObserver(this) >> > 

Or it might be less surprising to create an extension function you can tack onto your constructor calls. Then you can explicitly start the observation immediately. You’d have to make activity public, though. By defining it in an extension like this, your subclasses can call this and return themselves so you can chain it to constructor calls.

fun T.alsoBegin(): T < activity.lifecycle.addObserver(this) return this >val foo = SomeImplementation(myActivity).alsoBegin() 

Источник

Читайте также:  Java threads life cycle

Kotlin – “Leaking ‘this’ in constructor” warning should apply to final classes as well as open ones

In Kotlin if you have an open class which refers to this in its constructor or init block, you (quite rightly) get a compiler warning:

Leaking ‘this’ in constructor of non-final class

The reason for this is explained here.

My question is: why is this not reported when the class is final? If this is used in the init block before that block has completed, the object is still not in a fully constructed state, so shouldn’t the warning apply there too?

This can even lead to a situation where a val property seems to change at runtime. Take this code as an example:

class Listener < fun onCreated(leaker: Leaker) = println("Listener hears that leaker created with a value of $") > class Leaker(listener: Listener) < val myVal: Int init < listener.onCreated(this) myVal = 1 println("Leaker knows that it's been created with a value of $myVal") >> 

Using these objects as follows:

will result in the following output:

Listener hears that leaker created with a value of 0 Leaker knows that it's been created with a value of 1 

Notice that myVal is initially reported as being 0, then as being 1.

As can be seen, Leaker passes an instance of itself to Listener before Leaker has been fully constructed. Listener can then access the myVal property before it’s been initialized, so it’ll have the default value (0 in this case as it’s an integer). Later on Listener then changes the value of this property (to 1 in this example). This means that the program behaves as if a val has changed.

Should the compiler warn you about this?

Best Solution

tl;dr: https://youtrack.jetbrains.com/issue/KT-22044 is a good fit regarding this issue.

I will cite what Intellij IDEAs inspection called «Leaking ‘this’ in constructor» says about this:

  • Accessing a non-final property in constructor
  • Calling a non-final function in constructor
  • Using this as a function argument in a constructor of a non-final class
abstract class Base < val code = calculate() abstract fun calculate(): Int >class Derived(private val x: Int) : Base() < override fun calculate() = x >fun testIt() < println(Derived(42).code) // Expected: 42, actual: 0 >

I think that there should be warning nonetheless as you were able to access a non-initialized variable. The reason: the compiler already disallows direct access to uninitialized variables, i.e. the following will not compile:

but accessing it indirectly compiles and shows the default value of the variable type:

and there we also have a «leak», basically accessing some before it should 😉

Источник

«Leaking ‘this’ in constructor» warning should apply to final classes as well as open ones?

tl;dr: https://youtrack.jetbrains.com/issue/KT-22044 is a good fit regarding this issue.

I will cite what Intellij IDEAs inspection called «Leaking ‘this’ in constructor» says about this:

  • Accessing a non-final property in constructor
  • Calling a non-final function in constructor
  • Using this as a function argument in a constructor of a non-final class
abstract class Base < val code = calculate() abstract fun calculate(): Int >class Derived(private val x: Int) : Base() < override fun calculate() = x >fun testIt() < println(Derived(42).code) // Expected: 42, actual: 0 >

I think that there should be warning nonetheless as you were able to access a non-initialized variable. The reason: the compiler already disallows direct access to uninitialized variables, i.e. the following will not compile:

but accessing it indirectly compiles and shows the default value of the variable type:

and there we also have a «leak», basically accessing some before it should 😉

Java Constructor Tutorial - Learn Constructors in Java

Accessing Constructors of Parent Class in C++(Urdu/Hindi)

How to fix

Constructors in C++

JavaScript Constructor Functions

C# Constructors Tutorial | Mosh

Member Initializer Lists in C++ (Constructor Initializer List)

Class Constructors | C++ Object Oriented Programming Video Tutorial

she wouldn't be where she is today, no matter in politics or her true feelings - w0wdb

This Keyword in Java - How to use

Trouble shooting & Maintenance between SCADA & PLC. speed #Relay & #proximity sensor. Operation PC.

Cách đặt lệnh cắt lỗ và chốt lời (Vàng tăng điều chỉnh)

What are Classes, Objects, and Constructors?

Code Example: Constructors in Derived Class in Cpp | C++ Tutorials for Beginners #48

FIELDING TUTORIALS - LESSON 33 - DIRECT HIT - MAIN VIDEO LINK IN DESCRITION BOX - #SHORTS

Part 16 .Net c# OOPS: What is Private Constructor?Use of Private Constructor?

Constructor as a Class in JavaScript (Hindi)

36C3 - Open Source is Insufficient to Solve Trust Problems in Hardware

Lỗi thiếu file DLL sửa thiếu file dll hệ thống mới nhất How to Fix DLL file Missing Error

fix lỗi kb3033929 cho máy tính

Sửa lỗi không bắt điểm bất kì trên đoạn thẳng trong Auto CAD - LINH PRODUCTIONS

error on line 39 at column 26 Namespace prefix xlink for href on script is not defined - CSS

CS 285: Lecture 23, Open Problems, Part 3

Well. better than yesterday? C4 Energy https://pillar.io/majortom637/c4energy

Yoni Gibbs

Yoni Gibbs

Comments

Yoni Gibbs

In Kotlin if you have an open class which refers to this in its constructor or init block, you (quite rightly) get a compiler warning:

The reason for this is explained here. My question is: why is this not reported when the class is final? If this is used in the init block before that block has completed, the object is still not in a fully constructed state, so shouldn’t the warning apply there too? This can even lead to a situation where a val property seems to change at runtime. Take this code as an example:

class Listener < fun onCreated(leaker: Leaker) = println("Listener hears that leaker created with a value of $") > class Leaker(listener: Listener) < val myVal: Int init < listener.onCreated(this) myVal = 1 println("Leaker knows that it's been created with a value of $myVal") >> 
Listener hears that leaker created with a value of 0 Leaker knows that it's been created with a value of 1 

Notice that myVal is initially reported as being 0, then as being 1. As can be seen, Leaker passes an instance of itself to Listener before Leaker has been fully constructed. Listener can then access the myVal property before it’s been initialized, so it’ll have the default value (0 in this case as it’s an integer). Later on Listener then changes the value of this property (to 1 in this example). This means that the program behaves as if a val has changed. Should the compiler warn you about this?

Источник

[Solved]-«Leaking ‘this’ in constructor» warning should apply to final classes as well as open ones?-kotlin

tl;dr: https://youtrack.jetbrains.com/issue/KT-22044 is a good fit regarding this issue.

I will cite what Intellij IDEAs inspection called «Leaking ‘this’ in constructor» says about this:

  • Accessing a non-final property in constructor
  • Calling a non-final function in constructor
  • Using this as a function argument in a constructor of a non-final class
abstract class Base < val code = calculate() abstract fun calculate(): Int >class Derived(private val x: Int) : Base() < override fun calculate() = x >fun testIt() < println(Derived(42).code) // Expected: 42, actual: 0 >

I think that there should be warning nonetheless as you were able to access a non-initialized variable. The reason: the compiler already disallows direct access to uninitialized variables, i.e. the following will not compile:

but accessing it indirectly compiles and shows the default value of the variable type:

and there we also have a «leak», basically accessing some before it should 😉

  • «Leaking ‘this’ in constructor» warning should apply to final classes as well as open ones?
  • Kotlin calling non final function in constructor works
  • This type has a constructor and must be initialized here — Kotlin
  • kotlin how to refer outer-scope this in multi-layer apply functions
  • java static final in kotlin: Const ‘val’ initializer should be a constant value
  • Why are Kotlin classes final by default instead of open?
  • Error: Getters of lazy classes cannot be final Kotlin Spring Boot
  • Kotlin This Cursor should be freed up after use with #close
  • Custom gradle task that accesses top-level fails with «The constructor . should be annotated with @Inject»
  • Classes annotated with @Configuration could be implicitly subclassed and must not be final
  • There are multiple good constructors and Room will pick the no-arg constructor. How to solve this warning
  • Should Kotlin test classes be internal?
  • Kotlin for android and static final inner classes
  • How to fix ‘The feature «multi platform projects» is experimental and should be enabled explicitly’ warning in IntelliJ IDEA
  • Accessing outer scope with qualified this in extension functions for inner classes
  • Kotlin Class should have a single no-arg constructor
  • JUnit with Kotlin — This class does not have a constructor
  • Variables inside a constructor should be private or public in Kotlin
  • KMM error: This API is internal in ktor and should not be used. It could be removed or changed without notice
  • How to apply function to value defined in data class constructor before init method?
  • Kotlin inheritance: pass this as constructor argument
  • Unable to invoke no-args constructor for interface retrofit2.http.Url. Register an InstanceCreator with Gson for this type to fix this problem
  • Kotlin: secondary constructor with this keyword
  • mock final classes for both unit and UI tests
  • kotlin compiler return this type of warning
  • What should I do if I don’t want a devired class call base class’s constructor in Kotlin?
  • Kotlin’s safe-cast (or in this context «unsafe»-cast) hides possible NullPointerException warning by Android Studio
  • ValueAnimator Lint Error: This animation should be started with #start() [Recycle]
  • should I write this code in my fragment/activity or in my viewmodel?
  • Should I use FLAG_ACTIVITY_CLEAR_TOP in this case? how to use FLAG_ACTIVITY_CLEAR_TOP intent flag?

More Query from same tag

  • Why retrofit returns null in response body?
  • lateinit property not initialized when Activity is re-created
  • Convert String obtained from edittext to Integer in Kotlin language
  • Execution failed task ‘:app:kaptGenerateStubsDebugKotlin’
  • How can I fix this issue with flutter unity widget?
  • Kotlin n must be positive crash
  • How to get the first value from a list without exceptions in Kotlin?
  • Kotlin 1.5.2 data class hashcode( ) generated implementation will result in nullPointerExeption
  • How to impose generic constraints to the parameters and return values of a function argument of a generic Kotlin function?
  • How to set a SpannableString to an EditText in an Android Material TextInputLayout?
  • Replacing GlobalScope.launch with something better
  • Can comparison operator overloading in Kotlin be used to implement SQL like functionality?
  • how to change listView Item content in Kotlin in an effecient way?
  • How to use kotlinx.coroutines.withTimeout in kotlinx.coroutines.test.runTest?
  • how to get item value from ListView setOnItemClickListener?
  • AndroidX Room unresolved supertypes RoomDatabase
  • LocationManager’s requestLocationUpdates() creates a notification
  • Without AsyncTask, running a thread in background and updating the UI Thread
  • how to convert elapsed time from now to that date and pass that method to viewholder in kotlin
  • What’s the meaning of plus sign before a Kotlin method?
  • Android — Status bar notification not showing
  • How to write a method in Kotlin that will return a string from Firestore?
  • spring data rest kotlin associations POST
  • How do I ensure lateinit variable initialization before it is needed?
  • how to reference an item from layer-list.xml in activity
  • Can’t create secondary constructors in kotlin
  • How to detect leaked Disposable subscriptions in RxJava code?
  • Android R8 — Missing class: com.sun.javadoc.Doclet
  • Multiplying 2 numbers without buttons in Kotlin TextWatcher
  • how to specify maven compiler plugin order

Источник

Предупреждение «Утечка этого» в конструкторе должно относиться как к конечным классам, так и к открытым?

В Kotlin, если у вас есть класс open , который ссылается на this в своем конструкторе или блоке init , вы (совершенно справедливо) получите предупреждение компилятора:

Leaking ‘this’ in constructor of non-final class

Причина этого объясняется здесь.

Мой вопрос: почему этот нет сообщается, когда класс является окончательным? Если this используется в блоке init до того, как этот блок завершен, объект все еще не находится в полностью сконструированном состоянии, поэтому разве предупреждение не должно применяться и там?

Это может даже привести к тому, что свойство val изменится во время выполнения. В качестве примера возьмем этот код:

class Listener < fun onCreated(leaker: Leaker) = println("Listener hears that leaker created with a value of $") > class Leaker(listener: Listener) < val myVal: Int init < listener.onCreated(this) myVal = 1 println("Leaker knows that it's been created with a value of $myVal") >> 

Использование этих объектов следующим образом:

приведет к следующему выводу:

Listener hears that leaker created with a value of 0 Leaker knows that it's been created with a value of 1 

Обратите внимание, что myVal сначала отображается как 0, а затем как 1.

Как можно видеть, Leaker передает свой экземпляр Listener до того, как Leaker будет полностью сконструирован. Затем Listener может получить доступ к свойству myVal до его инициализации, поэтому оно будет иметь значение по умолчанию (в данном случае 0, поскольку это целое число). Позже Listener изменяет значение этого свойства (в этом примере на 1). Это означает, что программа ведет себя так, как если бы val был изменен.

Должен ли компилятор вас об этом предупредить?

Источник

Оцените статью