码出高效:Java开发手册-第2章(5)

简介: 本章开始讲解面向对象思想,并以Java 为载体讲述面向对象思想在具体编程语言中的运用与实践。当前主流的编程语言有50 种左右,主要分为两大阵营:面向对象编程与面向过程编程。面向对象编程(Object-Oriented Programming,OOP)是划时代的编程思想变革,推动了高级语言的快速发展和工业化进程。OOP 的抽象、封装、继承、多态的理念使软件大规模化成为可能,有效地降低了软件开发成本、维护成本和复用成本。面向对象编程思想完全不同于传统的面向过程编程思想,使大型软件的开发就像搭积木一样隔离可控、高效简单,是当今编程领域的一股势不可......

2.3.5 this 与 super

      对象实例化时,至少有一条从本类出发抵达Object 的通路,而打通这条路的两个主要工兵就是this 和super,逢山开路,遇水搭桥。但是this 和super 往往是默默无闻的,在很多情况下可以省略,比如:

  • 本类方法调用本类属性。
  • 本类方法调用另一个本类方法。
  • 子类构造方法隐含调用 super()。

      任何类在创建之初,都有一个默认的空构造方法,它是super() 的一条默认通路。构造方法的参数列表决定了调用通路的选择;如果子类指定调用父类的某个构造方法,super 就会不断往上溯源;如果没有指定,则默认调用super()。如果父类没有提供默认的构造方法,子类在继承时就会编译错误,如图2-4 所示。

4.jpg

图2-4 父类默认构造方法缺失

      如果父类坚持不提供默认的无参构造方法,必须在本类的无参构造方法中使用super 方式调用父类的有参构造方法,如public Son(){ super(123); }。

      一个实例变量可以通过this. 赋值另一个实例变量;一个实例方法可以通过this.调用另一个实例方法;甚至一个构造方法都可以通过this.调用另一个构造方法。如果this 和super 指代构造方法,则必须位于方法体的第一行。换句话说,在一个构造方法中,this和super 只能出现一个,且只能出现一次,否则在实例化对象时,会因子类调用到多个父类构造方法而造成混乱。

      由于this 和super 都在实例化阶段调用,所以不能在静态方法和静态代码块中使用this 和super 关键字。this 还可以指代当前对象, 比如在同步代码块synchronized(this){...} 中,super 并不具备此能力。但super 也有自己的特异功能,在子类覆写父类方法时,可以使用super 调用父类同名的实例方法。最后总结一下this和super 的异同点,如图2-5 所示。

5.jpg

图2-5 this和super的异同点

2.3.6 类关系

      关系是指事物之间存在单向或相互的作用力或者影响力的状态。类与类之间的关系可分成两种:有关系与没关系,这似乎是一句非常正确的废话,难点在于确定类与类之间是否存在相互作用。证明类之间没关系是一个涉及业务、架构、模块边界的问题,往往由于业务模型的抽象角度不同而不同,是一件非常棘手的事情。如果找到了没有关系的点,就可以如庖丁解牛一样,进行架构隔离、模块解耦等工作。有关系的情况下,包括如下6 种类型:

  • 【继承】extends (is-a)。
  • 【实现】implements (can-do)。
  • 【组合】类是成员变量 (contains-a)。
  • 【聚合】类是成员变量 (has-a)。
  • 【依赖】是除组合与聚合外的单向弱关系。比如使用另一个类的属性、方法,或以其作为方法的参数输入,或以其作为方法的返回值输出(depends-a)。
  • 【关联】是互相平等的依赖关系 (links-a)。

      继承和实现是比较容易理解的两种类关系。在架构设计中,要注意组合、聚合、依赖和关联这四者的区别。

      组合在汉语中的含义是把若干个独立部分组成整体,各个部分都有其独立的使用价值和生命周期。而类关系中的组合是一种完全绑定的关系,所有成员共同完成一件使命,它们的生命周期是一样的,极度容易混淆。组合体现的是非常强的整体与部分的关系,同生共死,部分不能在整体之间共享。

      聚合是一种可以拆分的整体与部分的关系,是非常松散的暂时组合,部分可以被拆出来给另一个整体。比如,汽车与轮子之间的关系就是聚合关系,轮子模块包括钢圈、轮胎、气嘴。轮子拆卸下来用到另一个汽车上是完全没有问题的。

      依赖是除组合和聚合外的类与类之间的单向弱关系,就是一个类A 用到类B,那么就说A依赖B,这种关系是偶然的、松散的、临时的。依赖使用另一个类的属性、方法,或以其作为方法的参数输入,或以其作为方法的返回值输出。本书认为,广义上的有向关联也等同于依赖。依赖往往是模块解耦的最佳点。

      关联即是互相平等的依赖关系,可以在关联点上进行解耦,但是解耦难度略大于依赖关系。

      在类图中,用空心的三角形表示继承,用实心的菱形表示组合,用空心的菱形表示聚合,用一条直线表示关联,这四者都是用实线连接的。用三角形来表示实现,用一个箭头表示依赖,与前面的区别是这两者都是用虚线连接的。在画类图时,菱形、箭头、三角形放在哪一侧呢?在很多类图中,这个处理是非常随意的。如果方向画反了,那么类结构的认知也就反了。有一个规律,有形状的图形符号一律放在权力强的这一侧,如表2-3 所示。

      随着业务和架构的发展,类与类的关系是会发生变化的,必须用发展的眼光看待类图。比如表2-3 中的Body 和Head,如果有一天,动物的脑袋可以随意地移植,那么就从组合关系变成聚合关系了。狗与狗绳之间的约束,虽然很弱,但是如果防疫局在狗绳上标记疫苗记录,那么它们之间的关系就会变强,就变成组合关系了。在业务重构过程中,往往会把原来强组合的关系拆开来,供其他模块调用,这就是类图的一种演变。

表2-3 类关系示例图

6.jpg

2.3.7 序列化

      内存中的数据对象只有转换为二进制流才可以进行数据持久化和网络传输。将数据对象转换为二进制流的过程称为对象的序列化(Serialization)。反之,将二进制流恢复为数据对象的过程称为反序列化(Deserialization)。序列化需要保留充分的信息以恢复数据对象,但是为了节约存储空间和网络带宽,序列化后的二进制流又要尽可能小。序列化常见的使用场景是RPC 框架的数据传输。常见的序列化方式有三种:

      (1) Java原生序列化。Java类通过实现Serializable接口来实现该类对象的序列化,这个接口非常特殊,没有任何方法,只起标识作用。Java 序列化保留了对象类的元数据(如类、成员变量、继承类信息等),以及对象数据等,兼容性最好,但不支持跨语言,而且性能一般。

      实现Serializable 接口的类建议设置serialVersionUID 字段值,如果不设置,那么每次运行时,编译器会根据类的内部实现,包括类名、接口名、方法和属性等来自动生成serialVersionUID。如果类的源代码有修改,那么重新编译后serialVersionUID的取值可能会发生变化。因此实现Serializable 接口的类一定要显式地定义serialVersionUID 属性值。修改类时需要根据兼容性决定是否修改serialVersionUID 值:

  • 如果是兼容升级,请不要修改 serialVersionUID 字段,避免反序列化失败。
  • 如果是不兼容升级,需要修改 serialVersionUID 值,避免反序列化混乱。

      使用Java 原生序列化需注意,Java 反序列化时不会调用类的无参构造方法,而是调用native 方法将成员变量赋值为对应类型的初始值。基于性能及兼容性考虑,不推荐使用Java 原生序列化。

      (2)Hessian 序列化。Hessian 序列化是一种支持动态类型、跨语言、基于对象传输的网络协议。Java 对象序列化的二进制流可以被其他语言(如C++、Python)反序列化。Hessian 协议具有如下特性:

  • 自描述序列化类型。不依赖外部描述文件或接口定义,用一个字节表示常用基础类型,极大缩短二进制流。
  • 语言无关,支持脚本语言。
  • 协议简单,比 Java原生序列化高效。

      相比Hessian 1.0,Hessian 2.0 中增加了压缩编码,其序列化二进制流大小是Java序列化的50%,序列化耗时是Java 序列化的30%,反序列化耗时是Java 反序列化的20%。

      Hessian 会把复杂对象所有属性存储在一个Map 中进行序列化。所以在父类、子类存在同名成员变量的情况下,Hessian 序列化时,先序列化子类,然后序列化父类,因此反序列化结果会导致子类同名成员变量被父类的值覆盖。

     (3)JSON 序列化。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。JSON 序列化就是将数据对象转换为JSON 字符串。在序列化过程中抛弃了类型信息,所以反序列化时只有提供类型信息才能准确地反序列化。相比前两种方式,JSON 可读性比较好,方便调试。

      序列化通常会通过网络传输对象,而对象中往往有敏感数据,所以序列化常常成为黑客的攻击点,攻击者巧妙地利用反序列化过程构造恶意代码,使得程序在反序列化的过程中执行任意代码。Java 工程中广泛使用的Apache Commons Collections、Jackson、fastjson 等都出现过反序列化漏洞。如何防范这种黑客攻击呢?有些对象的敏感属性不需要进行序列化传输,可以加transient 关键字,避免把此属性信息转化为序列化的二进制流。如果一定要传递对象的敏感属性,可以使用对称与非对称加密方式独立传输,再使用某个方法把属性还原到对象中。应用开发者对序列化要有一定的安全防范意识,对传入数据的内容进行校验或权限控制,及时更新安全漏洞,避免受到攻击。

相关文章
|
15天前
|
前端开发 Java 关系型数据库
基于Java+Springboot+Vue开发的鲜花商城管理系统源码+运行
基于Java+Springboot+Vue开发的鲜花商城管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的鲜花商城管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。技术学习共同进步
75 7
|
27天前
|
人工智能 安全 Java
智慧工地源码,Java语言开发,微服务架构,支持分布式和集群部署,多端覆盖
智慧工地是“互联网+建筑工地”的创新模式,基于物联网、移动互联网、BIM、大数据、人工智能等技术,实现对施工现场人员、设备、材料、安全等环节的智能化管理。其解决方案涵盖数据大屏、移动APP和PC管理端,采用高性能Java微服务架构,支持分布式与集群部署,结合Redis、消息队列等技术确保系统稳定高效。通过大数据驱动决策、物联网实时监测预警及AI智能视频监控,消除数据孤岛,提升项目可控性与安全性。智慧工地提供专家级远程管理服务,助力施工质量和安全管理升级,同时依托可扩展平台、多端应用和丰富设备接口,满足多样化需求,推动建筑行业数字化转型。
63 5
|
21天前
|
人工智能 Java 定位技术
Java 开发玩转 MCP:从 Claude 自动化到 Spring AI Alibaba 生态整合
本文以原理与示例结合的形式讲解 Java 开发者如何基于 Spring AI Alibaba 框架玩转 MCP。
563 84
|
20天前
|
人工智能 Java 定位技术
Java 开发玩转 MCP:从 Claude 自动化到 Spring AI Alibaba 生态整合
本文详细讲解了Java开发者如何基于Spring AI Alibaba框架玩转MCP(Model Context Protocol),涵盖基础概念、快速体验、服务发布与调用等内容。重点包括将Spring应用发布为MCP Server(支持stdio与SSE模式)、开发MCP Client调用服务,以及在Spring AI Alibaba的OpenManus中使用MCP增强工具能力。通过实际示例,如天气查询与百度地图路线规划,展示了MCP在AI应用中的强大作用。最后总结了MCP对AI开发的意义及其在Spring AI中的实现价值。
391 9
|
2月前
|
机器学习/深度学习 人工智能 NoSQL
JAVA接入DeepSeek大模型接口开发---阿里云的百炼模型
随着大模型的越来越盛行,现在很多企业开始接入大模型的接口,今天我从java开发角度来写一个demo的示例,用于接入DeepSeek大模型,国内的大模型有很多的接入渠道,今天主要介绍下阿里云的百炼模型,因为这个模型是免费的,只要注册一个账户,就会免费送百万的token进行学习,今天就从一个简单的可以执行的示例开始进行介绍,希望可以分享给各位正在学习的同学们。
270 3
JAVA接入DeepSeek大模型接口开发---阿里云的百炼模型
|
1月前
|
人工智能 Java 物联网
没有好的学历,Java开发未来的路应该怎么走?
在数字化时代,Java开发者即使没有高学历,也能通过拥抱新兴技术(如大模型应用与鸿蒙系统开发)、积累实战经验、持续学习新技能等途径实现职业突破。从参与开源项目到关注行业动态,再到规划技术专家或管理路线,建立人脉网络并利用教育平台提升能力,开发者可拓宽技术边界,适应日新月异的技术需求,在未来发展中占据一席之地。
|
3月前
|
人工智能 安全 IDE
一天成为Java开发高手:用飞算JavaAI实现十倍提效
“一天成为Java开发高手”曾被视为天方夜谭,但飞算JavaAI的出现改变了这一局面。这款AI开发助手通过智能引导、需求分析、自动化逻辑处理和完整代码工程生成,大幅简化了Java开发流程。它不仅帮助新手快速上手,还让资深开发者提高效率,减少调试时间。现在,参与“飞算JavaAI炫技赛”,展示你的开发实力,赢取丰厚奖品!
|
3月前
|
JavaScript 安全 Java
智慧产科一体化管理平台源码,基于Java,Vue,ElementUI技术开发,二开快捷
智慧产科一体化管理平台覆盖从备孕到产后42天的全流程管理,构建科室协同、医患沟通及智能设备互联平台。通过移动端扫码建卡、自助报道、智能采集数据等手段优化就诊流程,提升孕妇就诊体验,并实现高危孕产妇五色管理和孕妇学校三位一体化管理,全面提升妇幼健康宣教质量。
79 12
|
2月前
|
搜索推荐 Java Android开发
课时146:使用JDT开发Java程序
在 Eclipse 之中提供有 JDT环境可以实现java 程序的开发,下面就通过一些功能进行演示。 项目开发流程
|
2月前
|
存储 监控 数据可视化
SaaS云计算技术的智慧工地源码,基于Java+Spring Cloud框架开发
智慧工地源码基于微服务+Java+Spring Cloud +UniApp +MySql架构,利用传感器、监控摄像头、AI、大数据等技术,实现施工现场的实时监测、数据分析与智能决策。平台涵盖人员、车辆、视频监控、施工质量、设备、环境和能耗管理七大维度,提供可视化管理、智能化报警、移动智能办公及分布计算存储等功能,全面提升工地的安全性、效率和质量。