Home > other >  Get nullable property or throw exception
Get nullable property or throw exception

Time:01-05

I recently switch from java to kotlin. I have following method in my code and I would like to ask if there is better way how to write it in kotlin?

This is my parsing method which parse id from object obj which has nullable property nullableNestedObject and this object had id property.

fun parseId(obj: WrappingObject): Long {
    val myId = obj.nullableNestedObject?.myId

    if (myId === null) {
        logger.error("Id not found because of ...")
        throw InternalException("Id not found")
    }
    return myId
}

CodePudding user response:

You can simplify it a bit by putting the relevant code into a run() call:

fun parseId(obj: WrappingObject): Long
    = obj.nullableNestedObject?.myId
        ?: run {
            logger.error("ID not found because of...")
            throw InternalException("ID not found")
        }

Run is a scoping function that provides a simple way to group lines of code into a block.

(If the block didn't throw an exception, it would have to return a Long value too, of course.)

You'll notice I've made it into a single-expression function — it's shorter, and easier to see what it returns. (That's only appropriate for fairly short functions, though.)

(I've also capitalised ‘ID’, which is a bugbear of mine: it's an abbreviation, and pronounced as two letters, so both should be capitalised. Otherwise, it looks just like the term from psychoanalysis…)

Another change you might consider is to make it an extension function on WrappingObject:

fun WrappingObject.parseId(): Long
    = nullableNestedObject?.myId
        ?: run {
            logger.error("ID not found because of...")
            throw InternalException("ID not found")
        }

That way, it can be called as myWrappingObject.parseId(), just as if it were a method of WrappingObject. That can keep the namespace a little clearer, and lets your IDE suggest it.


As per Tulip's answer, this would be even simpler if you didn't need to call the logger as well:

fun parseId(obj: WrappingObject): Long
    = obj.nullableNestedObject?.myId
        ?: throw InternalException("ID not found")

When I write custom exceptions, I tend to write a log entry in the constructor, which enables that sort of simplicity as well as avoiding duplication of the log calls.

CodePudding user response:

If your Long value can be nullable, you can use this way, and check null or not null later

fun parseId(obj: WrappingObject): Long? {
    return obj.nullableNestedObject?.myId
}

CodePudding user response:

If you are looking for concise (i.e. minimal) code, I suggest using the elvis operator (?:) and the run scope function:

fun parseId(obj: WrappingObject): Long = obj.nullableNestedObject?.myId ?: run {
        logger.error("Id not found because of ...")
        throw InternalException("Id not found")
    }
  • Related