I'm burning cycles trying to understand why I'm getting a cast error when I know for a fact that it's a string.
Anyone else seen this in Kotlin? (it fails at the second to last line).
val stringValue =
if (attributesMap[it] !is String) { // same as !(obj is String)
gson.toJson(attributesMap[it])
} else if (attributesMap[it] == null) {
""
} else {
if (attributesMap[it] is String)
logger.info("it's a string wth...${attributesMap[it]}")
attributesMap[it] // <--- The stacktrace shows this line as the culprit, and the above "it's a string line" is printed out as well
}
Here's the error:
java.lang.ClassCastException: class java.util.ArrayList cannot be cast to class java.lang.String (java.util.ArrayList and java.lang.String are in module java.base of loader 'bootstrap')
CodePudding user response:
That is why it is always good idea to put { }
in if conditions. Given that you have no { }
, the condition if (attributesMap[it] is String)
only applies to a single line below. I think you wanted to write the following:
val stringValue =
if (attributesMap[it] !is String) { // same as !(obj is String)
gson.toJson(attributesMap[it])
} else if (attributesMap[it] == null) {
""
} else {
if (attributesMap[it] is String) {
logger.info("it's a string wth...${attributesMap[it]}")
attributesMap[it] // <--- The stacktrace shows this line as the culprit, and the above "it's a string line" is printed out as well
}
}
Or maybe:
val stringValue =
if (attributesMap[it] !is String) { // same as !(obj is String)
gson.toJson(attributesMap[it])
} else if (attributesMap[it] == null) {
""
} else if (attributesMap[it] is String) {
logger.info("it's a string wth...${attributesMap[it]}")
attributesMap[it] // <--- The stacktrace shows this line as the culprit, and the above "it's a string line" is printed out as well
} else {
// something else
}
CodePudding user response:
As @João Dias mentioned in his answer, the problem is the way you have written this if statement.
if (attributesMap[it] is String)
logger.info("it's a string wth...${attributesMap[it]}")
attributesMap[it] // <--- The stacktrace shows this line as the culprit, and the above "it's a string line" is printed out as well
attributesMap[it] // <--- The stacktrace shows this line as the culprit, and
is falling outside of the if
statement, so the right way is to put this inside a curly bracket like
if (attributesMap[it] is String) {
logger.info("it's a string wth...${attributesMap[it]}")
attributesMap[it] // <--- The stacktrace shows this line as the culprit, and the above "it's a string line" is printed out as well
} else {
//
}
CodePudding user response:
I guess the problem is that attributesMap[it]
is not a property itself. It's actually a function call attributesMap.get(it)
.
That's why compiler is not able to smart cast it.
Also, I am not sure of your order of if
statements. If attributesMap[it] !is String
is false, attributesMap[it] == null
will definitely be false.
Try this code, see if it works for you.
val value = attributes[it] // Store the value beforehand
val stringValue =
if(value == null)
""
else if(value is String)
value
else
gson.toJson(value)
You can also replace this if-else
ladder with a when
statement.