Java自定义对象打印:告别哈希码,拥抱内容显示

java自定义对象打印:告别哈希码,拥抱内容显示

在Java编程中,开发者经常会遇到一个常见问题:当尝试打印自定义类的对象实例或包含这些对象的集合(如数组)时,控制台输出的往往是一串类似内存地址的哈希码,而非对象内部的实际数据。例如,使用`Arrays.toString()`打印一个自定义对象数组时,我们可能会看到`[com.example.Student@1f32e575, com.example.Student@279f2327]`这样的输出。这对于调试和理解程序状态带来了不便。

Java对象默认的字符串表示

所有Java类都隐式或显式地继承自java.lang.Object类。Object类提供了一个默认的toString()方法实现,其源码大致如下:

public String toString() {    return getClass().getName() + "@" + Integer.toHexString(hashCode());}

这个默认实现返回的是“类名@对象的哈希码的十六进制表示”。这就是为什么在不进行任何修改的情况下,直接打印对象会看到哈希码的原因。Arrays.toString()方法在处理对象数组时,会遍历数组中的每个元素,并调用每个元素的toString()方法来获取其字符串表示,然后将这些表示连接起来。因此,要改变输出行为,我们需要改变对象本身的toString()行为。

解决方案:重写toString()方法

解决上述问题的核心在于重写自定义类中的toString()方法。通过在类中提供一个自己的toString()实现,我们可以定义对象在被转换为字符串时应该如何显示。这个方法应该返回一个包含对象关键属性的、人类可读的字符串。

立即学习“Java免费学习笔记(深入)”;

标书对比王 标书对比王

标书对比王是一款标书查重工具,支持多份投标文件两两相互比对,重复内容高亮标记,可快速定位重复内容原文所在位置,并可导出比对报告。

标书对比王 58 查看详情 标书对比王

以下是一个Student类的示例,演示了如何重写toString()方法:

import java.util.Arrays;import java.util.Comparator;import java.util.Scanner;public class Main {    private static class Student {        String fName; // First Name        String lName; // Last Name        int id;       // Student ID        int score;    // Score        public Student(String fName, String lName, int id, int score) {            this.fName = fName;            this.lName = lName;            this.id = id;            this.score = score;        }        public int getScore() {            return score;        }        @Override        public String toString() {            return "Student{id=" + id + ", fName='" + fName + "', lName='" + lName + "', score=" + score + "}";        }    }    // 辅助方法:检查字符串是否只包含字母    public static boolean isAlphabetic(String str) {        if (str == null || str.isEmpty()) {            return false;        }        for (char c : str.toCharArray()) {            if (!Character.isLetter(c)) {                return false;            }        }        return true;    }    public static void main(String[] args) {        Scanner input = new Scanner(System.in);        System.out.println("请输入学生数量:");        int k = input.nextInt(); // 学生数量        Student[] students = new Student[k];        for (int i = 0; i < k; ) {            System.out.println("请输入学生ID:");            int id = input.nextInt();            String fName;            do {                System.out.println("请输入学生名:");                fName = input.next();                if (!isAlphabetic(fName)) {                    System.out.println("输入错误!学生名必须只包含字母,请重新输入。");                }            } while (!isAlphabetic(fName));            String lName;            do {                System.out.println("请输入姓氏:");                lName = input.next();                if (!isAlphabetic(lName)) {                    System.out.println("输入错误!姓氏必须只包含字母,请重新输入。");                }            } while (!isAlphabetic(lName));            System.out.println("请输入分数:");            int score = input.nextInt();            students[i++] = new Student(fName, lName, id, score);        }        // 使用匿名内部类实现Comparator进行分数降序排序        Arrays.sort(students, new Comparator() {            @Override            public int compare(Student s1, Student s2) {                // 降序排列,所以用s2的分数减s1的分数                return Integer.compare(s2.getScore(), s1.getScore());            }        });        System.out.println("n排序后的学生信息:");        System.out.println(Arrays.toString(students));        input.close();    }}

在上述代码中,我们为Student类添加了一个toString()方法:

@Overridepublic String toString() {    return "Student{id=" + id + ", fName='" + fName + "', lName='" + lName + "', score=" + score + "}";}

通过@Override注解,我们明确表示这是对父类方法的一个重写。现在,当Arrays.toString(students)被调用时,它会为数组中的每个Student对象调用我们自定义的toString()方法,从而输出清晰、可读的学生信息,例如:

[Student{id=101, fName='Alice', lName='Smith', score=95}, Student{id=102, fName='Bob', lName='Johnson', score=88}]

注意事项与最佳实践

始终重写toString(): 对于所有自定义的数据类,强烈建议重写toString()方法。这不仅有助于调试,也能让日志输出更加有意义,提高代码的可维护性。提供有用的信息: toString()方法的实现应包含足以识别对象或描述其当前状态的关键属性。避免输出敏感信息。格式一致性: 尽量保持toString()输出格式的一致性,例如使用ClassName{field1=value1, field2=value2}的格式,这有助于自动化解析和日志分析。排序与Comparator: 示例中还展示了如何使用java.util.Comparator接口对自定义对象数组进行排序。Comparator允许我们定义一个外部的比较逻辑,而无需修改对象本身的类(与Comparable接口不同)。这里我们创建了一个匿名内部类来实现分数降序排序。对于Java 8及更高版本,可以使用Lambda表达式进一步简化:

Arrays.sort(students, (s1, s2) -> Integer.compare(s2.getScore(), s1.getScore()));

输入验证: 在示例代码中,我们修正了原始问题中输入验证的逻辑,确保用户输入有效值(例如,姓名只包含字母)后才能继续。这是健壮程序设计的重要组成部分。

通过正确重写toString()方法,我们可以有效地控制Java中自定义对象的字符串表示,从而极大地提升代码的可读性和调试效率。

以上就是Java自定义对象打印:告别哈希码,拥抱内容显示的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/308825.html

赞 (0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
客制化游戏键盘选什么?罗技G316X闪逸龙用粉紫潮流+8K性能给出答案
上一篇 2025年11月5日 04:22:38
thinkphp清除后台数据
下一篇 2025年11月5日 04:22:41

相关推荐

  • VSCode配置FPGA的CI/CD流程(自动化测试与部署指南)

    答案是:使用VSCode配置FPGA的CI/CD流程完全可行,通过tasks.json和launch.json集成脚本化构建、仿真、测试与烧录任务,结合Git版本控制与Docker环境封装,实现设计流程自动化;利用Cocotb等框架构建可复用、高覆盖率的自动化测试环境,并通过统一项目结构和CI/CD…

    2026年9月22日
    100
  • 【Linux】While循环吃hang行了?(图是一个毒)

    【Linux】While循环吃hang行了?(图是一个毒)【Linux】While循环吃hang行了?(图是一个毒)【Linux】While循环吃hang行了?(图是一个毒)【Linux】While循环吃hang行了?(图是一个毒)

    最近被一首歌曲洗脑了:心火烧,原名《情伴》,作为新中国的第一首流行歌曲,绝对是神曲的开山祖师呀,而在《向往的生活》中被宋丹丹老师、黄磊老师等演绎后,每天忍不住哼唱? 进入正题 这两天因为测试准备了一个脚本,流程就是类似需要登录各个服务器然后执行命令,从设计上看感觉非常简单: 将各服务器的IP全部写入…

    2026年9月22日 • 用户投稿
    000
  • 抖音飞鸽客服名称怎么改?抖店客服名称怎么改

    电商行业在我国经济中的地位日益凸显。为了满足消费者日益增长的服务需求,各大电商平台纷纷推出特色客服服务。抖音飞鸽客服作为抖音平台的官方客服,以其独特的服务模式和创新精神,赢得了广大用户的认可和好评。本文将从抖音飞鸽客服的名称改写、服务特色、行业影响等方面进行分析,以期为电商客服行业的发展提供借鉴。 …

    2026年9月22日
    000
  • Krita中如何导出AI生成的分层图片?保存多层图像的步骤

    .kra格式是保存AI分层图像的最佳选择,因其完整保留Krita特有的图层、蒙版、滤镜等编辑信息,确保后续修改不受限;若需跨软件协作,则应导出为PSD格式,尽管可能损失部分Krita专属功能,但兼容性最广;TIFF适合高质量印刷场景,但分层支持不稳定;OpenEXR适用于含深度、法线等通道的专业合成…

    2026年9月22日
    100
  • mysql怎么执行sql命令 mysql输入代码创建表详细步骤

    mysql怎么执行sql命令 mysql输入代码创建表详细步骤mysql怎么执行sql命令 mysql输入代码创建表详细步骤mysql怎么执行sql命令 mysql输入代码创建表详细步骤mysql怎么执行sql命令 mysql输入代码创建表详细步骤

    在mysql中执行sql并创建表的步骤如下:1.通过命令行或图形工具连接数据库,使用mysql -u 用户名 -p并输入密码登录;2.选择或创建数据库,用use database_name或create database语句;3.使用create table定义表结构,如字段名、数据类型、约束等,例…

    2026年9月22日 • 用户投稿
    100
  • laravel如何使用Pipeline模式处理复杂逻辑_Laravel Pipeline模式处理复杂逻辑方法

    Laravel Pipeline通过将复杂流程拆分为多个独立处理步骤,实现代码解耦与职责分离。以用户注册为例,可依次执行发送欢迎邮件、分配角色、记录日志等操作,每个步骤由单独类实现__invoke方法,通过Pipeline::send($user)->through([…])-&g…

    2026年9月22日
    200
  • Swift 3到5.1新特性整理

    tocSwift 5.1Swift 5.0Result类型Raw string自定义字符串插值动态可调用类型处理未来的枚举值从try?抹平嵌套可选检查整数是否为偶数字典compactMapValues()方法撤回的功能: 带条件的计数Swift 4.2CaseIterable协议警告和错误指令动态查…

    2026年9月22日
    000
  • AffinityDesigner如何导出AI生成的矢量图片?保存图像的步骤

    答案是选择合适的矢量格式并调整导出设置。在Affinity Designer中导出AI生成的矢量图时,应根据用途选择SVG(适用于Web)、PDF(适用于打印和跨平台分享)或EPS(适用于老旧系统);导出前需检查文本是否转曲、颜色模式是否正确,并优化路径与位图设置以平衡质量与文件大小;从其他AI工具…

    2026年9月22日
    000
  • php-gd怎么制作缩略图_php-gd生成高质量缩略图

    使用PHP-GD生成高质量缩略图需保持宽高比、选用imagecopyresampled进行重采样,并合理设置JPEG质量(80-95),同时处理PNG透明通道,避免图像失真或背景变黑。 使用 PHP-GD 制作高质量缩略图,核心在于正确处理图像缩放、保持宽高比、避免失真,并选择合适的图像质量参数。下…

    2026年9月22日
    000
  • MySQL安装后初始密码在哪里查看?

    MySQL安装后初始密码在哪里查看?MySQL安装后初始密码在哪里查看?MySQL安装后初始密码在哪里查看?MySQL安装后初始密码在哪里查看?

    mysql安装后的初始密码取决于安装方式和操作系统,通常可在错误日志中找到。1. 查看mysql错误日志:linux系统使用grep命令查找/var/log/mysqld.log或类似路径;windows系统在data目录下的hostname.err中搜索“temporary password”。2…

    2026年9月22日 • 用户投稿
    100
  • PHP日志记录怎么做_PHP中Monolog库实现灵活强大的日志系统

    Monolog是PHP中基于PSR-3标准的主流日志库,通过Composer安装后可轻松实现日志记录。使用Logger类创建实例并添加Handler(如StreamHandler写入文件、NativeMailerHandler邮件报警)来管理不同级别(debug、info、error等)日志输出,支…

    2026年9月22日
    200
  • 如何在RunwayML导出AI生成的4K图片?保存高清图像的教程

    要从RunwayML获得4K图像,需结合高分辨率生成设置与AI放大工具。首先在RunwayML中选择最高可用分辨率(如1024×1024或更高),并通过精细提示词和负面提示词优化生成质量;随后利用内置增强功能或外部AI放大工具(如Topaz Gigapixel AI、Upscayl)将图像…

    2026年9月22日
    100
  • mysql如何添加主键索引 mysql创建主键索引的步骤详解

    mysql如何添加主键索引 mysql创建主键索引的步骤详解mysql如何添加主键索引 mysql创建主键索引的步骤详解mysql如何添加主键索引 mysql创建主键索引的步骤详解mysql如何添加主键索引 mysql创建主键索引的步骤详解

    mysql中添加主键索引主要有三种方式:1. 创建新表时直接添加主键,可在列定义后使用primary key或在所有列定义后单独声明;2. 在已有表上通过alter table添加主键,需确保目标列非空且唯一,必要时先清洗数据;3. 添加复合主键,适用于多列组合才能唯一标识记录的情况。主键索引在in…

    2026年9月22日 • 用户投稿
    000
  • PHP数组如何定义和使用_PHP数组定义与使用详细教程

    PHP数组是存储和管理多个值的核心工具,支持索引、关联、混合及多维结构;通过方括号定义,可灵活访问、修改、添加或删除元素,并利用foreach高效遍历。 PHP数组是存储一系列值的强大工具,无论这些值是简单的数据项,还是更复杂的结构。它的核心思想就是把一堆相关的数据“打包”在一起,通过一个统一的名字…

    2026年9月22日
    000
  • Java中递归处理列表:排序验证与条件性最大值移除策略

    在处理列表数据时,我们常遇到需要根据特定条件修改列表的需求。本教程将深入探讨一个具体的场景:如何设计一个递归函数,该函数首先判断一个整数列表是否已按升序排序。如果列表已排序,则停止处理;如果未排序,则进一步检查列表中的最大值。仅当最大值位于列表的起始位置或末尾时,才将其移除,并对修改后的列表重复此过…

    2026年9月22日
    000
  • VSCode 如何配置 Python 虚拟环境 VSCode 配置 Python 虚拟环境的步骤​

    VSCode 如何配置 Python 虚拟环境 VSCode 配置 Python 虚拟环境的步骤​VSCode 如何配置 Python 虚拟环境 VSCode 配置 Python 虚拟环境的步骤​VSCode 如何配置 Python 虚拟环境 VSCode 配置 Python 虚拟环境的步骤​VSCode 如何配置 Python 虚拟环境 VSCode 配置 Python 虚拟环境的步骤​

    在vscode中配置python虚拟环境的核心是选择正确的解释器,确保项目依赖隔离;2. 首先在项目根目录使用python -m venv .venv创建虚拟环境,或使用conda、pipenv等工具;3. 在vscode中打开项目文件夹,通过ctrl+shift+p输入“python: selec…

    2026年9月22日 • 用户投稿
    100
  • 逛京东先人一步下单E人E本EBOOK X14 Air笔记本 补贴立省10%

    逛京东先人一步下单E人E本EBOOK X14 Air笔记本 补贴立省10%逛京东先人一步下单E人E本EBOOK X14 Air笔记本 补贴立省10%逛京东先人一步下单E人E本EBOOK X14 Air笔记本 补贴立省10%逛京东先人一步下单E人E本EBOOK X14 Air笔记本 补贴立省10%

    10月13日10:00,京东抢先首发e人e本全新力作——ebook x14 air ai轻薄笔记本电脑,以仅898克的极致轻盈机身和卓越的本地ai算力,重新定义高效移动办公新标准。新品官方定价7999元,京东首发期间可享国家补贴直降10%,实付仅需7199元,晒单再赠50元京东e卡,下单即送高品质内…

    2026年9月22日 • 用户投稿
    000
  • Pictory如何快速生成AI视频?从文本到AI视频的完整教程

    Pictory通过智能算法将文字脚本转化为专业AI视频,核心在于自动分析文本、匹配视觉素材、生成语音并初步剪辑。用户登录后选择“Script to Video”,粘贴结构清晰的脚本,AI会自动分割场景并推荐素材,支持手动调整场景划分、替换素材、上传自定义图片视频以增强品牌一致性。平台提供多语言AI语…

    2026年9月22日
    000
  • VSCode如何集成RabbitMQ管理工具 VSCode消息队列插件的使用指南

    vscode可通过安装benoit zuger开发的rabbitmq插件实现对rabbitmq的连接、消息查看、队列管理等操作;2. 使用步骤包括安装插件、添加连接、配置name、host、port、username、password和vhost参数;3. 连接成功后可在vscode内查看队列、发布…

    2026年9月22日
    000
  • 百家号发文章有字数要求吗?百家号文章最少多少字

    数字时代已经来临。百家号作为一款内容创作平台,成为了众多创作者展示才华、传播思想的舞台。百家号对于文章的字数要求,成为了许多创作者关注的焦点。本文将围绕百家号文章的字数要求,探讨其背后的原因、影响及应对策略。 一、百家号文章字数要求的原因 1. 提升内容质量 百家号对文章字数的要求,旨在提升内容质量…

    2026年9月22日
    100

发表回复

登录后才能评论
关注微信