What is the best way to define log TAG constant in Kotlin?

后端 未结 17 2114
暗喜
暗喜 2021-01-30 16:00

I\'m creating my first Kotlin classes in my Android application. Usually for logging purposes I have a constant with name TAG. What I would do in Java is:



        
相关标签:
17条回答
  • 2021-01-30 16:13

    Here is my extension function in kotlin, just add it in your extensions file.

    val Any.TAG: String
    get() {
        return if (!javaClass.isAnonymousClass) {
            val name = javaClass.simpleName
            if (name.length <= 23 || Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) name else
                name.substring(0, 23)// first 23 chars
        } else {
            val name = javaClass.name
            if (name.length <= 23 || Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
                name else name.substring(name.length - 23, name.length)// last 23 chars
        }
    }
    

    Then you can use TAG in any class like below:

    Log.d(TAG, "country list")
    
    0 讨论(0)
  • 2021-01-30 16:15

    In Kotlin you could create an extension, and call tag as a method call instead. This would mean you'd never have to define it inside each class, we can construct it dynamically each time we call the method:

    inline fun <reified T> T.TAG(): String = T::class.java.simpleName
    
    0 讨论(0)
  • 2021-01-30 16:15

    I Like TAG to be an extension function as suggested by Fredy Mederos.

    extending his answer to support anonymous classes :

     /**
     * extension function to provide TAG value
     */
    val Any.TAG: String
        get() {
            return if (!javaClass.isAnonymousClass) {
                val name = javaClass.simpleName
                if (name.length <= 23) name else name.substring(0, 23)// first 23 chars
            } else {
                val name = javaClass.name
                if (name.length <= 23) name else name.substring(name.length - 23, name.length)// last 23 chars
            }
        }
    
    0 讨论(0)
  • 2021-01-30 16:15

    In Android Studio, the usual way to rename something is to right-click the name, select Refactor->Rename. So, I think it's fine to do something like this,

    class MyClass {
        companion object {
            private const LOG_TAG = "MyClass"
        }
    }
    

    because if you rename the class MyClass like I described, then the IDE will suggest renaming your LOG_TAG String as well.

    Ultimately there are pros and cons of using this method vs. other methods. Because LOG_TAG is a String, there's no need to import the kotlin-reflect.jar, as you would if you set LOG_TAG equal to MyClass::class.simpleName. Also because the variable is declared as a compile-time constant with the const keyword, the generated bytecode is smaller since it doesn't need to generate more hidden getters, as described in this article.

    0 讨论(0)
  • 2021-01-30 16:18

    I found a way which is more "copy-paste"-able, since it doesn't require you to type the name of your class:

    package com.stackoverflow.mypackage
    
    class MyClass
    {
        companion object {
            val TAG = this::class.toString().split(".").last().dropLast(10)
        }
    }
    

    It's not the most elegant solution but it works.

    this::class.toString().split(".").last() will give you "com.stackoverflow.mypackage.MyClass$Companion" so you need the dropLast(10) to remove $Companion.

    Alternatively you can do this:

    package com.stackoverflow.mypackage
    
    class MyClass
    {
        val TAG = this::class.simpleName
    }
    

    But then the TAG member variable is no longer "static" and doesn't follow the recommended naming conventions.

    0 讨论(0)
  • 2021-01-30 16:21

    In general constants are all caps (ex. FOO) and located in the companion object:

    class MyClass {
        companion object {
            public const val FOO = 1
    
        }
    }
    

    and to define the TAG field you can use:

    private val TAG = MyClass::class.qualifiedName
    
    0 讨论(0)
提交回复
热议问题