You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin类属性值无法显示,打印出现@十六进制串问题求助

Kotlin对象打印显示@十六进制及类型判断问题解决

问题描述

定义Kotlin继承类并赋值后,打印对象时输出@后跟十六进制字符串,无法查看属性值;同时尝试通过character.type区分子类Jedi和Sith时,代码无法识别该变量。相关代码及输出如下:

原代码

open class Character(val name: String)
class Jedi(name: String, val age: Int) : Character(name)
class Sith(name: String, val hasMask: Boolean) : Character(name)

fun characterBuilder(input: String): Character {
    val (name, type, other) = input.split("-")
    return when (type) {
        "jedi" -> Jedi(name, other.toInt())
        "sith" -> Sith(name, other.toBoolean())
        else -> throw IllegalArgumentException("Unknown character type: $type")
    }
}

fun main() {
    val list = "luke-jedi-25 leia-jedi-25 darkvader-sith-true darksidiuos-sith-false".split(" ")
    val characters = list.map { characterBuilder(it) }

    // 代码无法识别该变量
    //val (jedis, siths) = characters.partition { character -> character.type == "jedi" }
    for (character in characters) { println(character) }
    // println("jedis: ${jedis.size}, siths: ${siths.size}")
}

程序输出

Jedi@728938a9
Jedi@21b8d17c
Sith@6433a2  
Sith@5910e440

问题1:打印对象输出@十六进制字符串的原因及解决方法

原因

Kotlin所有类默认继承自Any类,Any的toString()方法默认输出格式为类名@对象哈希码的十六进制值,因此直接打印对象只会显示这类字符串,无法展示属性内容。

解决方法

有两种常用实现方式:

  1. 手动重写toString()方法:在父类或子类中自定义输出格式,示例如下:
open class Character(val name: String) {
    override fun toString(): String {
        return "Character(name='$name')"
    }
}

class Jedi(name: String, val age: Int) : Character(name) {
    override fun toString(): String {
        return "Jedi(name='$name', age=$age)"
    }
}

class Sith(name: String, val hasMask: Boolean) : Character(name) {
    override fun toString(): String {
        return "Sith(name='$name', hasMask=$hasMask)"
    }
}
  1. 使用data class:Kotlin的data class会自动生成包含所有属性的toString()、equals()等方法,只需修改类定义即可:
open data class Character(val name: String)
data class Jedi(name: String, val age: Int) : Character(name)
data class Sith(name: String, val hasMask: Boolean) : Character(name)

修改后打印对象,即可看到包含属性值的输出,例如Jedi(name='luke', age=25)。


问题2:无法通过character.type区分Jedi和Sith的解决方法

原因

Character类及其子类Jedi、Sith均未定义type属性,因此调用character.type会报错。

解决方法

推荐两种方案:

  1. 使用is关键字做类型判断:直接判断对象的实际类型,这是Kotlin类型判断的常规方式,修改partition代码如下:
val (jedis, siths) = characters.partition { it is Jedi }

此时jedis会包含所有Jedi类型对象,siths包含Sith类型对象,后续可通过as关键字强转调用子类属性。

  1. 在父类中添加type属性:在Character类中新增type属性,子类构造时传入对应值,即可直接通过type属性判断:
open class Character(val name: String, val type: String)
class Jedi(name: String, val age: Int) : Character(name, "jedi")
class Sith(name: String, val hasMask: Boolean) : Character(name, "sith")

// 同步修改characterBuilder函数,传入type参数
fun characterBuilder(input: String): Character {
    val (name, type, other) = input.split("-")
    return when (type) {
        "jedi" -> Jedi(name, other.toInt())
        "sith" -> Sith(name, other.toBoolean())
        else -> throw IllegalArgumentException("Unknown character type: $type")
    }
}

// 此时partition代码可正常使用
val (jedis, siths) = characters.partition { it.type == "jedi" }

内容的提问来源于stack exchange,提问作者Charles Perry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 10:58:12