06. 详解 Java 的 Object 类和常见类

Object 类

java.lang.Object 作为所有 Java 类的祖先,编译系统默认继承 Object 类,Object 类包含了所有 Java 类的公共属性和方法。

  • Object() 构造方法
  • getClass():Class<?>
  • public boolean equals(Object obj) 比较两对象封装的数据是否相等;而比较运算符“==”在比较两对象变量时,只有当两个对象引用指向同一对象时才为真值。
  • hashCode()
  • public String toString() 该方法返回对象的字符串描述,建议所有子类都重写此方法。如果没有覆盖toString()方法,默认的字符串是 “类名@对象的十六进制哈希码”
  • wait(), wait(long), wait(long, int) 让当前线程进入阻塞状态
  • notify(), notifyAll 唤醒阻塞状态的线程
  • protected Object clone() 克隆对象
  • protected void finalize() 该方法 Java 垃圾回收程序在删除对象前自动执行。不建议开发者直接调用

hashCode 方法的说明

哈希码(hashCode),每个 Java 对象都有哈希码(hashCode)属性,哈希码可以用来标识对象,提高对象在集合操作中的执行效率。

小技巧:为了减轻书写重复 equals 和 hashCode 代码的负担,不建议手巧,而是可借助 IDEA 自动的生成功能和一些公共的类库进行辅助工作,例如使用 google/guava: Google core libraries for Java 来做生成这两方法。

equals 方法 和 toString 方法

和 hashCode 方法类似,这三个方法非常常用,建议所有类都进行复写。

包装类和装箱拆箱

包装类

在 Java 中 8 种基本数据类型不属于类,不具备“对象”的特征,没有成员变量和方法,不方便进行面向对象的操作。为此,Java 提供包装类(Wrapper Class)来将基本数据类型包装成类。

包装类也都很好记,除了 Integer 和 Character 外,其他类名称与基本类型基本一样,只是首字母大写。

基本数据类型 包装类

  1. boolean -> Boolean
  2. byte -> Byte
  3. char -> Character
  4. short -> Short
  5. int -> Integer
  6. long -> Long
  7. float -> Float
  8. double -> Double
数值包装类

这些数值包装类(Byte、Short、Integer、Long、Float和Double)都有一些相同特点。

1. 构造方法类似
每一个数值包装类都有两个构造方法,以 Integer 为例,Integer 构造方法如下:

  • 【已过时】Integer(int value):通过指定一个数值构造 Integer 对象。
  • 【已过时】Integer(String s):通过指定一个字符串 s 构造对象,s 是十进制字符串表示的数值。

更建议使用静态方法 valueOf。

2. 共同的父类
这 6 个数值包装类有一个共同的父类—Number,Number 是一个抽象类,除了这 6 个子类还有:AtomicInteger、AtomicLong、BigDecimal 和 BigInteger。Number 是抽象类,要求它的子类必须实现如下 6 个方法:

package java.lang;public abstract class Number implements java.io.Serializable {public abstract int intValue();public abstract long longValue();public abstract float floatValue();public abstract double doubleValue();public byte byteValue() {return (byte)intValue();}public short shortValue() {return (short)intValue();}
}

包装类与基本类型的转换代码结构是类似的,每种包装类都有一个静态方法 valueOf(),接受基本类型,返回引用类型,也都有一个实例方法 xxxValue() 返回对应的基本类型。

3. compareTo() 方法
每个包装类都实现了 Java API 中的 Comparable 接口。可以进行包装对象的比较。方法返回值是int,如果返回值是 0,则相等;如果返回值小于 0,则此对象小于参数对象;如果返回值大于 0,则此对象大于参数对象。

4. 字符串转换为基本数据类型
每一个数值包装类都提供一些静态 parseXXX(String) 方法将字符串转换为对应的基本数据类型。

5. 基本数据类型转换为字符串
每一个数值包装类都提供一些静态 toString() 方法实现将基本数据类型数值转换为字符串。对于 Integer 类型,字符串表示除了默认的十进制外,还可以表示为其他进制,如二进制、八进制和十六进制,包装类有静态方法进行相互转换。举例 Integer.toOctalString(15) 的输出结果为八进制的 17。

注意:那到底应该用静态的 valueOf 方法,还是使用 new 创建包装类型呢?
一般建议使用 valueOf 方法。new 每次都会创建一个新对象,而除了 Float 和 Double 外的其他包装类,都会缓存包装类对象,减少需要创建对象的次数,节省空间,提升性能。实际上,从 Java 9 开始,这些构造方法已经被标记为过时了,因此更加推荐使用静态的 valueOf 方法

Character 类

Character 类是 char 类型的包装类。Character 类常用方法如下:

  • Character(char value):构造方法,通过 char 值创建一个新的 Character 对象。
  • char charValue():返回此 Character 对象的值。
  • int compareTo(Character anotherCharacter):方法返回值是 int,如果返回值是 0,则相等;如果返回值小于 0,则此对象小于参数对象;如果返回值大于0,则此对象大于参数对象。
Boolean 类

Boolean类是 boolean 类型的包装类。

1. 构造方法
Boolean 类有两个构造方法,构造方法定义如下:
Boolean(boolean value):通过一个 boolean 值创建 Boolean 对象。
Boolean(String s):通过字符串创建 Boolean 对象。s 不能为 null,s如果是忽略大小写 “true” 则转换为 true 对象,其他字符串都转换为 false 对象。

2. compareTo() 方法
Boolean 类 有 int compareTo(Boolean 包装类对象) 方法,可以进行包装对象的比较。方法返回值是int,如果返回值是0,则相等;如果返回值小于 0,则此对象小于参数对象;如果返回值大于 0,则此对象大于参数对象。

3. 字符串转换为 boolean 类型

  • Boolean 包装类都提供静态 parseBoolean() 方法实现将字符串转换为对应的 boolean 类型,方法定义如下:
  • static boolean parseBoolean(String s):将字符串转换为对应的 boolean 类。s 不能为 null,s 如果是忽略大小写"true" 则转换为 true,其他字符串都转换为 false。

常用常量

包装类中除了定义静态方法和实例方法外,还定义了一些静态变量。对于 Boolean 类型,有:Boolean.TRUE,Boolean.FALSE。

所有数值类型都定义了 MAX_VALUE和 MIN_VALUE,表示能表示的最大/最小值。

Float 和 Double还定义了一些特殊数值,比如正无穷、负无穷、非数值。

Float 和 Double 中的常量非数值 NAN、无穷 INFINITY 的说明

java 浮点数运算中有两个特殊的情况:非数值 NAN、无穷 INFINITY。

1、INFINITY:
在浮点数运算时,有时我们会遇到除数为 0 的情况,那 java 是如何解决的呢?

我们知道,在整型运算中,除数是不能为 0 的,否则直接运行异常。但是在浮点数运算中,引入了无限这个概念,我们来看一下 Double 和 Float 中的定义。

// Double:
public static final double POSITIVE_INFINITY = 1.0 / 0.0;
public static final double NEGATIVE_INFINITY = -1.0 / 0.0;
// Float
public static final float POSITIVE_INFINITY = 1.0f / 0.0f;
public static final float NEGATIVE_INFINITY = -1.0f / 0.0f;

那么这些值对运算会有什么影响呢?

我们先思考一下下面几个问题:

  1. 无限乘以 0 会是什么?
  2. 无限除以 0 会是什么?
  3. 无限做除了乘以 0 以外的运算结果是什么?

1. 无限乘以0,结果为 NAN

System.out.println(Float.POSITIVE_INFINITY * 0); // output: NAN
System.out.println(Float.NEGATIVE_INFINITY * 0); // output: NAN

2. 无限除以 0,结果不变,还是无限

System.out.println((Float.POSITIVE_INFINITY / 0) == Float.POSITIVE_INFINITY); // output: true
System.out.println((Float.NEGATIVE_INFINITY / 0) == Float.NEGATIVE_INFINITY); // output: true

3. 无限做除了乘以 0 以外的运算,结果还是无限

System.out.println(Float.POSITIVE_INFINITY == (Float.POSITIVE_INFINITY + 10000)); // true
System.out.println(Float.POSITIVE_INFINITY == (Float.POSITIVE_INFINITY - 10000)); // true
System.out.println(Float.POSITIVE_INFINITY == (Float.POSITIVE_INFINITY * 10000)); // true
System.out.println(Float.POSITIVE_INFINITY == (Float.POSITIVE_INFINITY / 10000)); // true

要判断一个浮点数是否为 INFINITY,可用 isInfinite 方法

System.out.println(Double.isInfinite(Float.POSITIVE_INFINITY)); // output: true

2、NAN

java 中的 NAN 是这么定义的:

public static final double NaN = 0.0D / 0.0;

NAN 表示非数字,它与任何值都不相等,甚至不等于它自己,所以要判断一个数是否为 NAN 要用 isNAN 方法:

System.out.println(Double.isNaN(Float.NaN)); // output: true

自动装箱和拆箱

Java5 之后提供了拆箱(unboxing)功能,拆箱能够将包装类对象自动转换为基本数据类型的数值,而不需要使用 intValue() 或 doubleValue() 等方法。类似 Java5 还提供了相反功能,自动装箱(autoboxing) 底层调用了 valueOf() 方法,装箱能够自动地将基本数据类型的数值自动转换为包装类对象,从而不需要使用构造方法,也方便了书写。

注意: 小心,以下会运行期异常 NullPointerException

Integer obj = null;
int intVar = obj;

包装类的常量池

在前面,我们提到,创建包装类对象时,可以使用静态的 valueOf 方法,也可以直接使用 new,但建议使用 valueOf 方法,为什么呢?我们来看 Integer 的 valueOf 的代码(基于 Java8):

public static Integer valueOf(int i) {if (i >= IntegerCache.low && i <= IntegerCache.high)return IntegerCache.cache[i + (-IntegerCache.low)];return new Integer(i);
}
private static class IntegerCache {static final int low = -128;static final int high;static final Integer cache[];static {// high value may be configured by propertyint h = 127;String integerCacheHighPropValue =sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");if (integerCacheHighPropValue != null) {try {int i = parseInt(integerCacheHighPropValue);i = Math.max(i, 127);// Maximum array size is Integer.MAX_VALUEh = Math.min(i, Integer.MAX_VALUE - (-low) -1);} catch( NumberFormatException nfe) {// If the property cannot be parsed into an int, ignore it.}}high = h;cache = new Integer[(high - low) + 1];int j = low;for(int k = 0; k < cache.length; k++)cache[k] = new Integer(j++);// range [-128, 127] must be interned (JLS7 5.1.7)assert IntegerCache.high >= 127;}private IntegerCache() {}
}

IntegerCache 表示 Integer 缓存,其中的 cache 变量是一个静态 Integer 数组,在静态初始化代码块中被初始化,默认情况下,保存了 -128~127 共 256 个整数对应的 Integer 对象。

在 valueOf 代码中,如果数值位于被缓存的范围,即默认 -128~127,则直接从 Integer-Cache 中获取已预先创建的 Integer 对象,只有不在缓存范围时,才通过new创建对象。

通过共享常用对象,可以节省内存空间,由于 Integer 是不可变的,所以缓存的对象可以安全地被共享。Boolean、Byte、Short、Long、Character 都有类似的实现。这种共享常用对象的思路,是一种常见的设计思路,它有一个名字,叫享元模式,英文叫 Flyweight,即共享的轻量级元素。

其他类

Arrays 类

Arrays.toString 将数组转化为格式化后的字符串
Arrays.sort 将数组进行排序

Random 类

new Random().nextInt(10); // 0 - 10(但不包括本身) 的随机数

Scanner 类

Scanner sc = new Scanner()System.out.println(sc.nextLine());

System 类

获取时间戳 System.currentTimeMillis()

获取环境变量 System.getenv()

考一考

// 三种四舍五入的方法
System.out.println(Math.round(12.6));  // 记住是四舍五入即可 结果 13
System.out.println(Math.round(-12.6)); // 记住规则:四舍五入的取反 等于 取反的四舍五入 结果 -13System.out.println(Math.floor(12.6)); // 牢记结果趋向于坐标轴的反方向 结果 12.0
System.out.println(Math.floor(-12.6)); // 结果 -13.0System.out.println((int)12.6); // 记得取整数位即可 // 结果 12
System.out.println((int)-12.6); // 结果 -12System.out.println(1.0 / 0); // 结果为 Infinity

int 和 Integer 的区别

总的来说,int 是基本数据类型,用于表示整数。因为它是基本数据类型,不需要对象的创建和销毁;Integer 是一个类,用于对整数进行包装和提供一些额外的功能。在大多数情况下,使用 int 类型就可以满足需求,但在某些特定情况下,可能需要使用 Integer 类。

参考

  • 丁振凡编著,《Java 语言程序设计(第2版)》华东交大版,2014.9
  • 第 16 章 Java 常用类-图灵社区 http://www.ituring.com.cn/book/tupubarticle/17712
  • (转)Java DecimalFormat 用法(数字格式化)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/775324.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SQLite中的动态内存分配(五)

返回&#xff1a;SQLite—系列文章目录 上一篇&#xff1a;SQLite中的原子提交&#xff08;四&#xff09; 下一篇&#xff1a;SQLite使用的临时文件&#xff08;二&#xff09; ​概述 SQLite使用动态内存分配来获得 用于存储各种对象的内存 &#xff08;例如&#xff1a…

Django开发复盘

一、URL 对于一个不会写正则表达式的蒟蒻来说&#xff0c;在urls.py中就只能傻傻的写死名字&#xff0c;但是即便这样&#xff0c;还会有很多相对路径和绝对路径的问题&#xff08;相对ip端口的路径&#xff09;&#xff0c;因为我们网页中涉及到页面跳转&#xff0c;涉及到发送…

uniapp 用web-view 嵌套uniapp

1. uniapp 用web-view 嵌套uniapp uniapp开发的APP要嵌套uniapp开发的h5,并且APP后面还要打包H5,这就涉及app和h5之间的通信,h5和h5之间的通信。 1.1. 准备工作 无论是app和h5通信还是 h5和h5之间的通信都是需要引入web-view的sdk文件 我下载的是1.5.2版本,代码如下 !(functi…

目标检测系列模型发展历程

常见数据集&#xff1a; VOC-->COCO 模型发展&#xff1a; RCNN-->Fast RCNN-->Faster RCNN-->Mask RCNN 这一系列的模型&#xff08;RCNN、Fast RCNN、Faster RCNN、Mask RCNN&#xff09;代表了计算机视觉特别是在物体检测和分割领域的一系列重大进展。下面&a…

神经网络:梯度下降法更新模型参数

作者&#xff1a;CSDN _养乐多_ 在神经网络领域&#xff0c;梯度下降是一种核心的优化算法&#xff0c;本文将介绍神经网络中梯度下降法更新参数的公式&#xff0c;并通过实例演示其在模型训练中的应用。通过本博客&#xff0c;读者将能够更好地理解深度学习中的优化算法和损…

【LeetCode】20. 有效的括号(Java自用版)

栈 首先&#xff0c;我们定义一个isValid方法&#xff0c;该方法接受一个字符串s作为参数&#xff0c;并返回一个布尔值来表示该字符串是否有效。 public boolean isValid(String s) {// 如果字符串为空&#xff0c;则自然是有效的if (s.isEmpty())return true;// 创建一个栈…

帆软报表在arm架构的linux

有朋友遇到一个问题在部署帆软报表时遇到报错。 问 我在 arm架构的linux服务器上部署帆软报表遇到了一个棘手的问题&#xff0c;你有空帮忙看下嘛。 我看后台日志报的错是 需要升级 gcc、libmawt.so &#xff0c;是系统中缺少Tomcat需要的依赖库&#xff0c;你之前处理过类似…

超级会员卡积分收银系统源码:积分+收银+商城三合一小程序 带完整的安装代码包以及搭建教程

信息技术的迅猛发展&#xff0c;移动支付和线上购物已经成为现代人生活的常态。在这样的背景下&#xff0c;商家对于能够整合收银、积分管理和在线商城的综合性系统的需求日益强烈。下面&#xff0c;罗峰给大家分享一款超级会员卡积分收银系统源码&#xff0c;它集积分、收银、…

机器学习(复试)

学习分类 其学习形式主要分为&#xff1a;有监督学习、无监督学习、半监督学习 有监督 有监督学习&#xff08;supervised learning&#xff09;&#xff0c;需要你事先需要准备好要输入数据&#xff08;训练样本&#xff09;与真实的输出结果&#xff08;参考答案) 预测结…

vector类(一)

文章目录 vector介绍和使用1.vector的介绍2.vector的使用2.1 vector的定义2.2 vector iterator的使用2.3 vector空间增长问题2.4 vector增删查改2.5 vector迭代器失效问题 3.vector 在OJ中的使用 vector介绍和使用 1.vector的介绍 vector是表示 可变大小数组的 序列容器。 就…

四、harmonyos实操一个toDoItem待办列表

官方讲的很大概&#xff0c;有些细节得去看源码才能知道&#xff0c;不过还是撸出来一个简易版的的item了 import image from ohos.multimedia.image;Entry // 表示入口 Component struct Index {State isComplete:boolean false;private totalTasks: Array<string> […

《数据结构学习笔记---第五篇》---链表OJ练习上

目录 CM11链表分割 OR36 链表的回文结构 160.相交链表 141&142环形链表 CM11链表分割 step1:思路分析 1.首先可以想到&#xff0c;我们可以将原链表的元素划分到两个新的链表之中&#xff0c;由于必须保持顺序&#xff0c;所以新链表我们要用尾插。 2.为了方便进行尾插我…

自动化与智能化并行:数字化运维体系助力企业腾飞

文章目录 文章目录 文章目录 一、引言二、数字化运维体系的核心要素三、构建数字化运维体系的策略四、数字化运维体系的实施与挑战主要内容读者对象 一、引言 随着信息技术的迅猛发展&#xff0c;数字化转型已成为企业提升竞争力、实现可持续发展的必由之路。在数字化转型的过…

JSP – 支持WORD上传的富文本编辑器

1.下载示例 https://gitee.com/xproer/zyoffice-tinymce5 2.引入组件 3.配置转换接口 效果 泽优Office文档转换服务(zyOffice) 功能&#xff1a;一键导入Word转HTML&#xff0c;不装控件&#xff0c;不装Office&#xff0c;任意平台兼容(Windows,macOS,Linux,安卓Android,苹果…

Java文件基本操作入门指南

Java文件基本操作入门指南 文章目录 Java文件基本操作入门指南前言一、文件的基本操作1、文件的创建2、文件的写入3、文件的读取4、文件的删除 二、进阶操作与技巧1、文件的复制与移动2、文件内容的追加3、随机访问文件4、文件路径与名称操作 三、最佳实践与注意事项1、异常处理…

flutter boost 如何从native跳转到flutter页面

Flutter Boost 是一个 Flutter 插件&#xff0c;它可以帮助开发者在原生应用和 Flutter 应用之间无缝跳转。以下是一些基本步骤&#xff0c;展示了如何使用 Flutter Boost 从原生&#xff08;Native&#xff09;页面跳转到 Flutter 页面。 ### 1. 配置 Flutter Boost 在你的 …

【GPU系列】选择最适合的 CUDA 版本以提高系统性能

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

什么是数据仓库

数据仓库定义 数据仓库,按照传统的定义,数据仓库是一个面向主题的、集成的、持久的(非易失的)、反映历史变化(随时间变化),用来支持管理人员决策的数据集合。 通俗讲,企业希望能够更快得处理比较多的数据,数据仓库由此诞生。 就像是企业的财务系统。各个部门(面向主…

nvm安装以后,node -v npm 等命令提示不是内部或外部命令

因为有vue2和vue3项目多种&#xff0c;所以为了适应各类版本node,使用nvm管理多种node版本&#xff0c;但是当我按教程安装nvm以后&#xff0c;nvm安装以后&#xff0c;node -v npm 等命令提示不是内部或外部命令 首先nvm官网网址&#xff1a;https://github.com/coreybutler/…

数据结构——栈(C语言版)

前言&#xff1a; 在学习完数据结构顺序表和链表之后&#xff0c;其实我们就可以做很多事情了&#xff0c;后面的栈和队列&#xff0c;其实就是对前面的顺序表和链表的灵活运用&#xff0c;今天我们就来学习一下栈的原理和应用。 准备工作&#xff1a;本人习惯将文件放在test.c…