Sekret — risk-free toString() of Kotlin data class?


Kotlin compiler automatically generates equals, hashCode, componentN, copy and toString functions for Data classes. It’s super useful because you as a developer don’t have to spend time writing boilerplate code and testing. But there is one problem (at least for me) — a result of toString() will contain all properties of Data class.

Let me explain why it can be a problem. For example in Android development, if you use MVI pattern, Views tend to have a single render() that accepts a state to render on the screen:

data class ViewState(
val username: String,
val password: String,
val isButtonEnabled: Boolean
// PS: never keep passwords in String

Great, now you may want to add some logging system to able to understand what your customer’s behavior or what they have seen before a crash or for just debugging purpose:

fun render(viewState: ViewState) {"render $viewState")

Logger class can use Log.d() internally and just prints on logcat. Or it can be your own analytics system that sends data to the web or just saves in files. It can even be Google Analytics, Crashlytics.log or any other 3rd party vendor. Your application can be a reason for PII, passwords, credit card info or any other sensitive data leakage. I agree that the logging system should be much smarter than just saving everything and everywhere.

It’s not only about Android, but it can also be an issue everywhere especially on microservices architecture where every component is independent and logs all in / out data. It can happen in Repository with sealed class results + data classes, Actions from View to Presenter, State of StateMachine, etc…


There are many ways how we can exclude our properties from toString() result. But all of them need manual work. Since developers are lazy I’ve implemented a tool that helps with this. Sekret is Kotlin compiler plugin which changes generated Java bytecode of toString() method during the compilation process. You just need to annotate your property with a special annotation and that’s it!

data class Data(
val username: String,
@Secret val password: String
print(Data("", "123456"))// prints out
// Data(, password=■■■)

More info on Github:

Perhaps JetBrains will allow changing toString() body with an out-of-box solution like Transient annotation for serialization.

Senior Android Developer at Agoda

Love podcasts or audiobooks? Learn on the go with our new app.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Anatolii Afanasev

Anatolii Afanasev

Senior Android Developer at Agoda

More from Medium

Kotlin vs Java Example: Part - 6 | Erselan Khan

Kotlin/Gradle/JUnit starter project

Fix Android Studio Gradle Java 8 error

Kotlin for Java Developers