4

How can I achieve this java code's analog in Kotlin?

class Item {
    private String text = "";

    public String getText() {
        return text;
    }

    public void setText(String str) {
        if(str == null){
            text = "";
        } else {
            text = str;
        }
    }

}

So whenever I set null value for text, it's value replaced with empty string. I want exactly the same behavior but in Kotlin, because I'm working with Java classes in Kotlin code, which may return some null values. Checking for nullability everytime before setting fields value is not a good idea, because it can be forgotten by accident, and give an exception at runtime.

2
  • 2
    Hit Ctrl-shift-A (or Cmd-shift-A on Mac), then type "convert java file to Kotlin". Commented Apr 22, 2019 at 21:27
  • What's wrong with an exception at runtime? If you're testing your code thoroughly, it's a lot easier to debug an exception than to debug silently transformed data. Commented Apr 22, 2019 at 22:03

4 Answers 4

7

The simplest way is text.orEmpty()

text.orEmpty() for a String? will return "" if null, or the original string

The best alternate option is text ?: ""

Sign up to request clarification or add additional context in comments.

Comments

0
class Item {
    private var text: String = ""

    fun getText() = text

    fun setText(str: String?) {
        text = str ?: ""
    }
}

2 Comments

this.text = str ?: "" ?
Make the getter public with private setter instead of getText().
0

The Java code in the question implements a property whose value can't be null, but whose setter allows null (converting it to a default value).  (Java doesn't have direct support for properties, so you have to code the field, getter, and setter by hand.)

This doesn't really have an idiomatic Kotlin equivalent.  The direct translation would be:

class Item {
    var text: String = ""
        set(value) { field = value ?: "" }
}

This declares a non-nullable property with a default value.  (Like all Kotlin properties, its field is private; it also has a getter method and — because it's a var — a setter method, both of which are public because the no other visibility was specified.)  And it overrides the setter to substitute the default value if null is passed.

If called from Java code, then I think the above would handle it as expected.  (I haven't tested it.)

But because the Kotlin compiler knows that the field is not nullable, it wouldn't allow you to call the setter with a null value in the first place; this is where it differs from the Java version.

So if it were called only from other Kotlin code, the ?: "" would never be used, and so the setter wouldn't need to be overridden.  The most natural Kotlin translation would be simply:

class Item {
    var text: String = ""
}

2 Comments

You exactly described my problem. Setter is called only from kotlin code, but the value is taken from Java library, which may return null. So I was searching for elegant way to easily overcome these null values and set empty strings if null passed
If the setter is called only from Kotlin, then I'd suggest using a simple non-nullable property (as per my last example), and fixing nulls when you call the setter, e.g. myItem.text = someValueFromJava ?: "". (That's concise, and keeps the null handling nearer the Java.) Or, if that happens a lot, perhaps adding a separate method to Item e.g. fun setTextHandlingNull(value: String?) { text = value ?: "" }. (That makes it more obvious to the caller what's happening.)
0

Some times the IDE will tell you that is unnecesary, so I made function and named ifNull then I passed the value.

    private fun ifNull(value: String?): String {

    return value ?: " "
}

Now, use it like this.

TextView.text = ifNull(name)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.