Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Non-static method cannot be referenced from a static context – Java to Kotlin – Android

I am trying to create a Logger class in android , which would log message only if its a debug build.

object Logger2 {

private const val TAG = Constants.LOGGING_TAG

fun d(message : Any?){
    if (BuildConfig.DEBUG)
        Log.d(TAG , message.toString())
}

fun d(message: Any? , e : Exception?){
    if (BuildConfig.DEBUG)
        Log.d(TAG , message.toString(), e)
}
fun e(message : Any?){
    if (BuildConfig.DEBUG)
        Log.e(TAG , message.toString())
}

fun e(message: Any? , e : Exception?){
    if (BuildConfig.DEBUG)
        Log.e(TAG , message.toString(), e)
}

fun w(message : Any?){
    if (BuildConfig.DEBUG)
        Log.w(TAG , message.toString())
}

fun w(message: Any? , e : Exception?){
    if (BuildConfig.DEBUG)
        Log.w(TAG , message.toString(), e)
}

fun v(message : Any?){
    if (BuildConfig.DEBUG)
        Log.v(TAG , message.toString())
}

fun v(message: Any? , e : Exception?){
    if (BuildConfig.DEBUG)
        Log.v(TAG , message.toString(), e)
}

}

Since I want all of my other activities and classes to be able to use this logger class , I created the class as a kotlin object.

This works fine in all other kotlin classes ,I was able to call the log methods like this , This is how I call from the kotlin classes.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Logger2.e("message")

But from a Java class when I try to do the same call . I get this sort of error.

enter image description here

Can someone tell me what exactly does that error mean and how to fix it ? The method from which I am calling the Logger2 class is not even static . Then why this error ?

>Solution :

Kotlin objects are not exactly equivalent to Java static. They are singletons. They exist as a class instance. When accessed from Java, the singleton instance must be retrieved through the static field named INSTANCE:

Logger2.INSTANCE.e("foo");

If you want the compiler to instead make each of these functions static so you don’t have to retrieve them through the singleton instance, then mark them as @JvmStatic:

object Logger2 {

    @JvmStatic
    fun d(message : Any?){
        if (BuildConfig.DEBUG)
            Log.d(TAG , message.toString())
    } 

    //...
}

The documentation about this is here.

If you’re curious about the reasons why it was designed this way:

  • The distinction between a Java class and its static members is sort of confusing. What do you even call the collection of static fields and methods of a Java class minus all the non-static members? It isn’t any one thing.
  • Kotlin objects are flexible. They are an instance of a class just like any other class instance or function object or enum value, so you can pass them around as function arguments, and they can implement interfaces or be subclasses of other classes. They can be the receiver of extension functions. etc.

In general the above features would be incompatible with static methods of a Java class so that’s why these functions aren’t compiled as Java static methods by default. Marking one of these functions as @JvmStatic is creating an exception, and with that exception comes some restrictions…the function cannot rely on any non-@JvmStatic or non-@JvmField members of the object.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading