Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to access companion object from object instance in kotlin?

Simple sample class with companion object

class MyClass {
  companion object {
     val test = 25
  }
}

The value test can be accessed from by MyClass.test, but how to access from an instance of MyClass? If I have val sample = MyClass(), how do I then access test from sample? sample::class.test is not correct....is there a way?

The question has been raised: 'Why not simply use MyClass.test'?

I prefer to keep the question to 'how' rather than 'why', but since it has been asked I will try the 'why'. The same could also apply to the methods. Why not have static functions in a class and simply call Class.function() and pass the object as one of the parameters?

Consider when working with an object passed as a more abstract base class, with several classes possible for the object you are working with.

You could make a switch and for each possbile class and access the value (or function) from the appropriate class that way, but the idea of polymorphism is that you should be able to access class attributes like a method (even though a function method code for for all members of the same class) or a value common to all members of the class from an instance of an object of that class.

My solution so far is to simply implement the equivalent of MyClass in with test as a static

public class MyClass {
    static Integer test = 25;
    public Integer testGetter(){ return test; }    
}

There are easy solutions to this in Java, C++, python etc.... (I will provide code samples for each is that helps) and i would think there will be a better solution in kotlin than resorting to using Java.

The kotlin companion object provides an alternative (and with advantages) to the static for situations where class attributes are accessed without an object instance (like factories), but there is another use of static for cases where although an object instance may be available, a static is appropriate since a single attribute can be shared by all members of the class and the attribute is not instance dependant.

like image 807
innov8 Avatar asked Oct 19 '17 09:10

innov8


People also ask

How do you access companion object in another class Kotlin?

In Kotlin, we can easily create a thread-safe singleton using the object declaration. If we declare the object inside a class, we have an option to mark it as a companion object. In terms of Java, the members of the companion object can be accessed as static members of the class.

How do you use the companion object in Kotlin?

To create a companion object, you need to add the companion keyword in front of the object declaration. The output of the above code is “ You are calling me :) ” This is all about the companion object in Kotlin. Hope you liked the blog and will use the concept of companion in your Android application.

How do you initialize a companion object in Kotlin?

All we have to do is declare an init block inside the companion object of a class. This way, we get the same behavior as Java's static block. Put simply, when the JVM is going to initialize the enclosing class, it will execute the init block inside the companion object.


2 Answers

The problems is that while object properties are accessible from outside the class provided they are not public, but properties of the companion object are not. This means adding getters (and if relevant setters) for any companion object properties to be accessed externally to the class.

class MyClass{
  companion object{
     val test = 25
  }
  var staticTest get() = test  // getter for test
}

then all that is needed for access is::

sample.staticTest

Or you can provide access to the companion object...

class MyClass{
    companion object{
        val test = 25
    }
    var companion = Companion
}

Then allowing full access to anything in the companion

like image 66
innov8 Avatar answered Nov 07 '22 03:11

innov8


Using reflection, you can go via companionObject:

sample::class.companionObject?.memberProperties?.find { it.name == "test" }
like image 22
s1m0nw1 Avatar answered Nov 07 '22 05:11

s1m0nw1