Creating anonymous object with inline function. Does it contain a leak of Enclosing Class? - memory-leaks

As you know each anonymous object in java contains hidden reference to enclosing class.
But with kotling things get more complicated.
Lambda is another representation of anonymous class, but in kotlin it compiles not straightforward, because if lambda didn't capture a reference of enclosing class explicitely than it would be compiled like nested, not inner class (anonymous class) and is safe from the leak.
But what about inline functions. Consider the code below
class A {
fun test(){
val it = withReference {
//todo make sth
}
}
}
inline fun withReference(crossinline action: () -> Unit) = object: Reference {
override fun method1() {
action()
}
override fun method2() {
}
}
interface Reference {
fun method1()
fun method2()
}
As i know inline function would be compiled like non-wrapped code to the A class, so the question is open.
Does the anonymous object: Reference contain a link to enclosing class A, which could lead to a memory leak?
PS: i have read this article, but it doesn't contain an answer to my case

I used the decompiler of IntelliJ and there is no reference to the outer A
public final class A$test$$inlined$withReference$1 implements Reference {
public void method1() {
}
public void method2() {
}
}
If the lambda references a variable from the outer class A like this:
class A {
val valFromA = 10;
fun test(){
val it = withReference {
println("use $valFromA")
}
}
}
Then the decompiler shows the reference to the A object:
public final class A$test$$inlined$withReference$1 implements Reference {
// $FF: synthetic field
final A this$0;
public A$test$$inlined$withReference$1(A var1) {
this.this$0 = var1;
}
public void method1() {
String var1 = "use " + this.this$0.getValFromA();
System.out.println(var1);
}
public void method2() {
}
}

If you think about it, the withReference function has no way of referring to the outer scope that it gets inlined into, therefore it has no reason to contain a reference to the scope that it's called from. You don't even know what class it's being called in, or if it's even called inside a class, for that matter.
For this specific case, here's the decompiled and simplified bytecode of the withReference function:
public static Reference withReference(final Function0 action) {
return new Reference() {
public void method1() {
action.invoke();
}
public void method2() {
}
};
}
At the places where it gets inlined, there's of course no call to this function, this one is for Java interop only. Kotlin call sites all get their own class generated to represent this object depending on what code you pass into the action parameter. For your call of the test function, a class like is generated:
public final class A$test$$inlined$withReference$1 implements Reference {
public void method1() {
//todo make sth
}
public void method2() {
}
}
And this is what's instantiated in the test method:
public final class A {
public final void test() {
Reference it = new A$test$$inlined$withReference$1();
}
}

Related

How to override Groovy variable and method using anonymous class?

I have the following code. I have an abstract JobParams, a class extending that abstract GradleJobParams, and a gjp variable with value using anonymous class declaration.
I want to test the overriding behavior of groovy. I can override the method setupRoot() but not the property testVar, why is that?
Tested on: https://groovyconsole.appspot.com/script/5146436232544256
abstract class JobParams {
int root
def testVar=1
def setupRoot () {
println("The root");
}
def printTestVar () {
println("The testVar:" + testVar);
}
}
class GradleJobParams extends JobParams {
}
def gjp = [
testVar:3,
setupRoot:{
println("Override root");
}
] as GradleJobParams;
println("Starting");
gjp.printTestVar();
gjp.setupRoot();
The result is:
Starting
The testVar:1
Override root
Java (and thus Groovy) does not support overriding fields from the parent class with subclassing. Instead, it uses a mechanism called hiding fields:
Hiding Fields
Within a class, a field that has the same name as a field in the superclass hides the superclass's field, even if their types are different. Within the subclass, the field in the superclass cannot be referenced by its simple name. Instead, the field must be accessed through super, which is covered in the next section. Generally speaking, we don't recommend hiding fields as it makes code difficult to read.
Source: https://docs.oracle.com/javase/tutorial/java/IandI/hidevariables.html
It can be simply illustrated with the following example in Java:
final class SubclassHiddingFieldExample {
static abstract class A {
int value = 10;
void printValue1() {
System.out.println(value);
}
void printValue2() {
System.out.println(this.value);
}
void printValue3() {
System.out.println(((B)this).value);
}
}
static class B extends A {
int value = 12;
}
public static void main(String[] args) {
final B b = new B();
b.printValue1();
b.printValue2();
b.printValue3();
}
}
Output:
10
10
12
As you can see, only printValue3 prints out 3, because it cast this explicitly to B class.
Now, if you look at the decompiled bytecode of your JobParams class, you can see that the printTestVar method code is an equivalent of the following Java code:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
import groovy.lang.GroovyObject;
import groovy.lang.MetaClass;
import org.codehaus.groovy.runtime.callsite.CallSite;
public abstract class JobParams implements GroovyObject {
private int root;
private Object testVar;
public JobParams() {
CallSite[] var1 = $getCallSiteArray();
byte var2 = 1;
this.testVar = Integer.valueOf(var2);
MetaClass var3 = this.$getStaticMetaClass();
this.metaClass = var3;
}
public Object setupRoot() {
CallSite[] var1 = $getCallSiteArray();
return var1[0].callCurrent(this, "The root");
}
public Object printTestVar() {
CallSite[] var1 = $getCallSiteArray();
return var1[1].callCurrent(this, var1[2].call("The testVar:", this.testVar));
}
public MetaClass getMetaClass() {
MetaClass var10000 = this.metaClass;
if (var10000 != null) {
return var10000;
} else {
this.metaClass = this.$getStaticMetaClass();
return this.metaClass;
}
}
public void setMetaClass(MetaClass var1) {
this.metaClass = var1;
}
public Object invokeMethod(String var1, Object var2) {
return this.getMetaClass().invokeMethod(this, var1, var2);
}
public Object getProperty(String var1) {
return this.getMetaClass().getProperty(this, var1);
}
public void setProperty(String var1, Object var2) {
this.getMetaClass().setProperty(this, var1, var2);
}
public int getRoot() {
return this.root;
}
public void setRoot(int var1) {
this.root = var1;
}
public Object getTestVar() {
return this.testVar;
}
public void setTestVar(Object var1) {
this.testVar = var1;
}
}
You can see that the line that prints out the value of the testVar field is represented by:
return var1[1].callCurrent(this, var1[2].call("The testVar:", this.testVar));
It means that no matter what value of testVar your subclass defines, the printTestVar method uses testVar field defined in the JobParams class. Period.
Using Groovy auto getter methods
There is one way you to implement the expected behavior. Every class field in Groovy has a getter method associated with that field compiled by Groovy for you. It means that you can access testVar by calling the getTestVar() method generated by the Groovy compiler. You can use it to override the value returned by a getter method for any field from the subclass. Consider the following example:
abstract class JobParams {
int root
def testVar=1
def setupRoot () {
println("The root");
}
def printTestVar () {
println("The testVar:" + getTestVar()); // <-- using a getTestVar() method instead a testVar field
}
}
class GradleJobParams extends JobParams {
}
def gjp = [
getTestVar: 3, // <-- stubbing getTestVar() method to return a different value
setupRoot:{
println("Override root");
}
] as GradleJobParams;
println("Starting");
gjp.printTestVar();
gjp.setupRoot();
Output:
Starting
The testVar:3
Override root

Execute an objects method without making a new instance

How can I execute Print from within TestObject?
class Program
{
private int Value;
static void Main()
{
TestObject test = new TestObject();
Program p1 = new Program();
Program p2 = new Program();
p1.Value = 1;
p2.Value = 2;
p1.Print();
p2.Print();
}
private void Print()
{
Console.Write(Value.ToString());
Console.ReadKey();
}
}
class TestObject
{
// How to execute p1.Print here?
}
There are multiple ways to do this:
Pass Program directly to TestObject
Pros:
Simple change
Cons:
You will have to make Print public
You will expose other things in Program
You're coupling TestObject to Program directly
Here's sample code:
class Program
{
static void Main()
{
TestObject test = new TestObject(this);
}
public void Print()
{
Console.Write(Value.ToString());
Console.ReadKey();
}
}
class TestObject
{
public TestObject(Program p)
{
p.Print();
}
}
Pass a delegate to TestObject
Pros:
Simple change
Doesn't have to make Print public
Only exposes 1 method to TestObject
Cons:
The coupling is TestObject wants to do something, not TestObject wants access to something that does something
Here's sample code:
class Program
{
static void Main()
{
TestObject test = new TestObject(() => Print());
}
private void Print()
{
Console.Write(Value.ToString());
Console.ReadKey();
}
}
class TestObject
{
public TestObject(Action print)
{
print();
}
}
Implement an interface in Program and pass it to TestObject
Pros:
Only exposes what the interface exposes
Easier to implement other places (better to say "need this interface" than "needs a delegate", clearer contract specification)
No coupling to a specific type, coupling is to any object that meets certain criteria - implements an interface
Cons:
None relevant (in my opinion)
Here's sample code:
interface IPrintable
{
void Print();
}
class Program : IPrintable
{
static void Main()
{
TestObject test = new TestObject(this);
}
public void Print()
{
Console.Write(Value.ToString());
Console.ReadKey();
}
}
class TestObject
{
public TestObject(IPrintable p)
{
p.Print();
}
}
Conclusion: My advice would be to pick the interface way. Clearer design, easier to extend without having multiple delegates being passed around.

An object reference is required for the non-static field, method, or property

I have created the class name cls1 and created method called GrantAccess().but the i am not able to access _entities.it's showing the below error
"Error 1 An object reference is required for the non-static field, method, or property 'Path._entities".
public class cls1
{
private readonly DBEntities _entities;
public cls1 ()
{
if (_entities == null)
{
_entities = new DBEntities();
}
}
public static void GrantAccess()
{
if (Settings.DbLog == "1")
{
_entities.II_CCLog("Excuting the GrantAccess() Method");
}
}
}
The above method is called in some other class.
public void GetCConfig()
{
cls1.GrantAccess();
}
GrantAccess is a static method while _entities is not a static variable. So you need to make GrantAccess a non-static method or you have to make _entities a static variable.
Static methods and properties cannot access non-static fields and events in their containing type, and they cannot access an instance variable of any object unless it is explicitly passed in a method parameter.
Or create a new instance of DBEntities in the static GrantAccess method and perform your operation on this instance.
public static void GrantAccess()
{
if (Settings.DbLog == "1")
{
DBEntities entities = new DBEntities();
entities.II_CCLog("Excuting the GrantAccess() Method");
}
}
first you have to create an object of cls1 in the class where you are calling the method of the cls1 class and then with from that object reference you will be able to call the method GrantAccess();. You can create object by following way :-
variable_name = new class_name( );
You are mixing static code with instance code. If you're working with objects, don't make your method GrantAccess static:
public void GrantAccess()
{
if (Settings.DbLog == "1")
{
_entities.II_CCLog("Excuting the GrantAccess() Method");
}
}
Then you'll have to create an instance of cls1:
public void GetCConfig()
{
var instance = new cls1();
cls1.GrantAccess();
}
You should also make cls1 disposable and call .Dispose() on _entities after you're finishied using it.
public class cls1 : IDisposable
{
...
public void Dispose()
{
_entities.Dispose();
}
Put the cls1 instance into a using block, like this:
public void GetCConfig()
{
using(var instance = new cls1())
{
cls1.GrantAccess();
}
}
Finally, the following line is not needed, because _entities will always be null at the beginning of the constructor.
if (_entities == null)
{
I'd suggest reading some basic documentation about object oriented programming with c#, for example:
https://msdn.microsoft.com/en-us/library/dd460654.aspx

How is IClock resolved with SystemClock in this example?

I am trying to learn IOC principle from this screencast
Inversion of Control from First Principles - Top Gear Style
I tried do as per screencast but i get an error while AutomaticFactory try create an object of AutoCue. AutoCue class has contructor which takes IClock and not SystemClock. But my question is , in screencast IClock is resolved with SystemClock while inside AutomaticFactory .But in my code , IClock does not get resolved . Am i missing something ?
class Program
{
static void Main(string[] args)
{
//var clarkson = new Clarkson(new AutoCue(new SystemClock()), new Megaphone());
//var clarkson = ClarksonFactory.SpawnOne();
var clarkson = (Clarkson)AutomaticFactory.GetOne(typeof(Clarkson));
clarkson.SaySomething();
Console.Read();
}
}
public class AutomaticFactory
{
public static object GetOne(Type type)
{
var constructor = type.GetConstructors().Single();
var parameters = constructor.GetParameters();
if (!parameters.Any()) return Activator.CreateInstance(type);
var args = new List<object>();
foreach(var parameter in parameters)
{
var arg = GetOne(parameter.ParameterType);
args.Add(arg);
}
var result = Activator.CreateInstance(type, args.ToArray());
return result;
}
}
public class Clarkson
{
private readonly AutoCue _autocue;
private readonly Megaphone _megaphone;
public Clarkson(AutoCue autocue,Megaphone megaphone)
{
_autocue = autocue;
_megaphone =megaphone;
}
public void SaySomething()
{
var message = _autocue.GetCue();
_megaphone.Shout(message);
}
}
public class Megaphone
{
public void Shout(string message)
{
Console.WriteLine(message);
}
}
public interface IClock
{
DateTime Now { get; }
}
public class SystemClock : IClock
{
public DateTime Now { get { return DateTime.Now; } }
}
public class AutoCue
{
private readonly IClock _clock;
public AutoCue(IClock clock)
{
_clock = clock;
}
public string GetCue()
{
DateTime now = _clock.Now;
if (now.DayOfWeek == DayOfWeek.Sunday)
{
return "Its a sunday!";
}
else
{
return "I have to work!";
}
}
}
What you basically implemented is a small IoC container that is able to auto-wire object graphs. But your implementation is only able to create object graphs of concrete objects. This makes your code violate the Dependency Inversion Principle.
What's missing from the implementation is some sort of Register method that tells your AutomaticFactory that when confronted with an abstraction, it should resolve the registered implementation. That could look as follows:
private static readonly Dictionary<Type, Type> registrations =
new Dictionary<Type, Type>();
public static void Register<TService, TImplementation>()
where TImplementation : class, TService
where TService : class
{
registrations.Add(typeof(TService), typeof(TImplementation));
}
No you will have to do an adjustment to the GetOne method as well. You can add the following code at the start of the GetOne method:
if (registrations.ContainsKey(type))
{
type = registrations[type];
}
That will ensure that if the supplied type is registered in the AutomaticFactory as TService, the mapped TImplementation will be used and the factory will continue using this implementation as the type to build up.
This does mean however that you now have to explicitly register the mapping between IClock and SystemClock (which is a quite natural thing to do if you're working with an IoC container). You must make this mapping before the first instance is resolved from the AutomaticFactory. So you should add the following line to to the beginning of the Main method:
AutomaticFactory.Register<IClock, SystemClock>();

MS TEst: Method not executed when base class is generic

Not duplicate of: Inherited test class from generic base is ignored in MSTest
In my case, the test classes are in the same namespace/assembly.
When unittesting classes which have a lot in common, I would like to use a base test class with a generic parameter. I have boiled the problem down to the following, where my base test method is not being executed, but ONLY in the generic case.
Non-generic: Base test method is EXECUTED:
[TestClass]
public class DerivedTestClass : BaseUnitTest
{
protected override string ReturnMeSomething(object obj)
{
return "test1" + obj.ToString();
}
[TestMethod]
public void derived_test()
{
// This is executed
}
}
[TestClass]
public abstract class BaseUnitTest
{
[TestMethod]
public void base_test()
{
// This is executed
}
protected abstract string ReturnMeSomething(object obj);
}
Generic: Base test method in generic base class is NOT EXECUTED:
[TestClass]
public class DerivedTestClass : BaseUnitTest<string>
{
protected override string ReturnMeSomething(string s)
{
return "test1" + s;
}
[TestMethod]
public void derived_test()
{
// This is executed
}
}
[TestClass]
public abstract class BaseUnitTest<T>
{
[TestMethod]
public void base_test()
{
// This is NOT executed
}
protected abstract string ReturnMeSomething(T t);
}
Can anyone tell me the reason for this?
After a few days, this suddenly works (!!). If anyone ever experiences this same, odd behavior, please write a comment here. I would suggest anyone to reboot and clean+rebuild everything and try again.

Resources