java cron工具类_Java工具类之:包装类
我们都知道,JDK 其实给我们提供了很多很多 Java 开发者已经写好的现成的类,他们其实都可以理解成工具类,比如我们常见的集合类,日期相关的类,数学相关的类等等,有了这些工具类,你会发现它能很大程度的帮你节省时间,能很方便的实现你的需求。当然,没有这些包,你也能实现你的需求,但是你需要时间,今天我们主要是来学习一下包装类。
一、包装类介绍
1、为什么需要包装类?
我们知道 Java 语言是一个面向对象的编程语言,但是 Java 中的基本数据类型却不是面向对象的,但是我们在实际使用中经常需要将基本数据类型转换成对象,便于操作,比如,集合的操作中,这时,我们就需要将基本类型数据转化成对象,所以就出现了包装类。
2、包装类是什么呢?
包装类,顾名思义就是将什么经过包装的类,那么是将什么包装起来的呢,显然这里是将基本类型包装起来的类。包装类的作用就是将基本类型转成对象,将基本类型作为对象来处理。
Java 中我们知道,基本数据类型有8个,所以对应的包装类也是8个,包装类就是基本类型名称首字母大写。但Integer 和 Character 例外,它们显示全称,如下面表格所示:
基本数据类型对应包装类byteByteshortShortintIntegerlongLongfloatFloatdoubleDoublecharCharacterbooleanBoolean
二、包装类的继承关系
通过阅读 Java8 的 API 官方文档或者看源代码我们可以得知8个包装类的继承关系如下:
通过以上的继承关系图,我们其实可以这样记忆,包装类里面有6个与数字相关的都是继承自 Number 类,而其余两个不是与数字相关的都是默认继承 Object 类。通过看 API 官方文档,我们还可以得知这8个包装类都实现了Serializable , Comparable 接口。比如下图的 Integer 类
public final class Integer extends Number implements Comparable<Integer> {}
三、包装类的使用方法(基本操作)
接下来关于包装类的讲解我就讲Integer包装类,其他的都依此类推,用法和操作都是差不多的,只是名字不一样而已。
1、包装类的构造方法
8个包装类都有带自己对应类型参数的构造方法,其中8个包装类中除了Character还有构造方法重载,参数是String类型的。
Integer one = new Integer(666);Integer two = new Integer("666");
2、包装类的自动拆装箱
在了解自动拆装箱之前,我们得先知道什么是拆箱和装箱。其实拆装箱主要应对基本类型与包装类型的相互转换问题。
- **装箱:**将基本类型转换成包装类型的过程叫做装箱。
- **拆箱:**将包装类型转换成基本类型的过程叫做拆箱。
其实,在 JDK1.5 版本之前,是没有自动拆装箱的,开发人员要手动进行装拆箱:
//手动装箱,也就是将基本类型10转换为引用类型
Integer integer = new Integer(10);
//或者
Integer integer1 = Integer.valueOf(10);
//手动拆箱,也就是将引用类型转换为基本类型
int num = integer.intValue();
而在在 JDK1.5 版本之后,为了减少开发人员的工作,提供了自动装箱与自动拆箱的功能。实现了自动拆箱和自动装箱,如下方代码所示:
//自动装箱
Integer one = 1;
//自动拆箱
int two = one + 10;
其实以上两种方式本质上是一样得,只不过一个是自动实现了,一个是手动实现了。至于自动拆装箱具体怎么实现的我这里不做深入研究。
四、包装类的缓存机制
我们首先来看看以下代码,例1:
public static void main(String[] args) {Integer i1 = 100; Integer i2 = 100; Integer i3 = new Integer(100);Integer i4 = new Integer(100);System.out.println(i1 == i2);
//true System.out.println(i1 == i3);
//false System.out.println(i3 == i4);
//false System.out.println(i1.equals(i2));
//true System.out.println(i1.equals(i3));
//true System.out.println(i3.equals(i4));
//true
}
当我们修改了值为200的时候,例2:
public static void main(String[] args) {
Integer i1 = 200; Integer i2 = 200; Integer i3 = new Integer(200); Integer i4 = new Integer(200);
System.out.println(i1 == i2);
//false System.out.println(i1 == i3);
//false System.out.println(i3 == i4);
//false System.out.println(i1.equals(i2));
//true System.out.println(i1.equals(i3));
//true System.out.println(i3.equals(i4));
//true
}
通过上面两端代码,我们发现修改了值,第5行代码的执行结果竟然发生了改变,为什么呢?首先,我们需要明确第1行和第2行代码实际上是实现了自动装箱的过程,也就是自动实现了 Integer.valueOf 方法,其次,==比较的是地址,而 equals 比较的是值(这里的 eauals 重写了,所以比较的是具体的值),所以显然最后五行代码的执行结果没有什么疑惑的。既然==比较的是地址,例1的第5行代码为什么会是true呢,这就需要我们去了解包装类的缓存机制。
其实看Integer类的源码我们可以发现在第780行有一个私有的静态内部类,如下:
private static class IntegerCache { static final int low = -128; static final int high; static final Integer cache[];static { // high value may be configured by property int 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_VALUE h = 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() {
}
}
我们知道,静态的内部类是在整个 Integer 加载的时候就已经加载完成了,以上代码初始化了一个 Integer 类型的叫 cache 的数组,取值范围是[-128, 127]。缓存机制的作用就是提前实例化相应范围数值的包装类对象,只要创建处于缓存范围的对象,就使用已实例好的对象。从而避免重复创建多个相同的包装类对象,提高了使用效率。如果我们用的对象范围在[-128, 127]之内,就直接去静态区找对应的对象,如果用的对象的范围超过了这个范围,会帮我们创建一个新的 Integer 对象,其实下面的源代码就是这个意思:
public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i);
}
所以 例1 代码里,i1 和i2 是100,值的范围在[-128, 127],所以直接区静态区找,所以i1和i2指向的地址是同一个,所以 i1==i2;而在例2的代码里,i1 和i2 是200,值的范围不在在[-128, 127],所以分别创建了一个新的对象,放在了堆内存里,各自指向了不同的地址,所以地址都不同了,自然 i1 不等于 i2。
通过分析源码我们可以发现,只有 double 和 float 的自动装箱代码没有使用缓存,每次都是 new 新的对象,其它的6种基本类型都使用了缓存策略。使用缓存策略是因为,缓存的这些对象都是经常使用到的(如字符、-128至127之间的数字),防止每次自动装箱都创建一次对象的实例。
五、包装类和基本数据类型的区别
- 默认值不同
包装类的默认值是null,而基本数据类型是对应的默认值(比如整型默认值是0,浮点型默认值是0.0)
- 存储区域不同
基本数据类型是把值保存在栈内存里,包装类是把对象放在堆中,然后通过对象的引用来调用他们
- 传递方式不同
基本数据类型变量空间里面存储的是值,传递的也是值,一个改变,另外一个不变,而包装类属于引用数据类型,变量空间存储的是地址(引用),传递的也是引用,一个变,另外一个跟着变。
java cron工具类_Java工具类之:包装类相关推荐
- java sqlite 工具类_Java 工具类 - JDBC通用操作基类 BaseDao
封装了增删改查功能 适用于MySQL.Oracle.SQLServer.DB2.Sybase.JTDS.PostgreSql.SQLite.Derby.H2.HSQLDB.ODBC 等等数据库,有需要 ...
- java 比较器类_java常用类——比较器
Comparable和Comparator接口都是为了对类进行比较,众所周知,诸如Integer,double等基本数据类型,java可以对他们进行比较,而对于类的比较,需要人工定义比较用到的字段比较 ...
- java filereader类_Java FileReader类
FileReader类从InputStreamReader类继承而来.该类按字符读取流中数据.可以通过以下几种构造方法创建需要的对象. 在给定从中读取数据的 File 的情况下创建一个新 FileRe ...
- java scanner 类_Java Scanner类
全屏 要从标准输入读取数字,必须将其读取为字符串并将其解析为数字.java.util包中的Scanner类根据模式读取并解析基本类型和字符串中的文本.文本源可以是InputStream,文件,Stri ...
- 时间日期类JAVA包含地区属性_Java常用类 | 时间和日期类
开发中经常涉及到时间与日期,记录下Java中与时间和日期相关的API JDK8之前与时间日期相关的类 java.lang.System类 System类提供了一个公共的静态方法currentTimes ...
- java复用类_java复用类
1. toString() 每一个非基本类型都有一个toString()方法:当编译器需要从对象获取一个string时,该对象的toString()方法就会被调用. 示例: class WaterSo ...
- java继承孙子类_Java:类与继承
Java:类与继承 对于面向对象的程序设计语言来说,类毫无疑问是其最重要的基础.抽象.封装.继承.多态 这四大特性都离不开类,只有存在类,才能体现面向对象编程的特点,今天我们就来了解一些类与继承的相关 ...
- java高级类_Java高级类特性(一)
权限类内同包不同包子类不同包非子类 private √ × × × default √ √ × × protected √ √ √ × public √ √ √ √ 四.super关键字的使用 pac ...
- java 大数类_Java大数类介绍
java能处理大数的类有两个高精度大整数BigInteger和高精度浮点数BigDecimal,这两个类位于java.math包内,要使用它们必须在类前面引用该包:import java.math.B ...
- java常用class类_java常用类
java常用类 内部类 1.成员内部类:在一个类的内部定义一个完整的类 例如:外部类public class Body{ 内部类class Header{ } } 内部类可以直接访问外部类的私有成员, ...
最新文章
- 语义分割:基于openCV和深度学习(一)
- SOFAMosn配置模型
- 异构数据库转换工具的结构说明
- c#v2.0 扩展特性 翻译(1)
- hdu oj1095题解
- 网易云信再被列入Gartner最新发布的两份CPaaS市场报告
- mysql 安装 运维_MySQL自动化运维之安装篇
- ug建模文本怎么竖着_UG建模知乎答疑练习小集锦
- PC电脑 屏幕竖直截长屏、本地视频转码、本地视频转gif动画、gif压缩等
- 11.1.1 认识StringBuffer类(1)
- 金融产品经理---理财公司业务模式剖析
- 你真的需要一个微信公众号吗?
- java开发简历专业技能怎么写,附赠复习资料
- 《皇帝内经》养生法则
- 高通芯片校准中的RGI、ICQ是什么意思,校准的特征化是什么意思?(转)
- 计算机世界:“狗日的”腾讯 搅局者还是终结者
- HTML5基础实例(三)
- Ubuntu 22.04 LTS root登录、修改当前用户名和主机名
- 考研计算机专业英语面试自我介绍,2017年计算机专业研究生英语面试自我介绍...
- 代理IP的主要用途和使用注意事项
热门文章
- hibernate中PO对象的三种状态分析以及session中的一些方法的区别
- 基于C#.NET的--Windows进程管理工具
- linux的kerne启动过程,linux
- 四川省内二本计算机公立好的大学排名,四川有哪些二本院校是公立的?附四川省公立二本大学排名及分数线...
- java嵌套类型 无法隐藏外层类型_java内部类深入详解 内部类的分类 特点 定义方式 使用...
- php年龄查询表单设计,PHP 处理表单
- python2.7输入函数_Python2.7的用户输入函数有问题,无法让这些输入与程序一起工作...
- java婚庆网站源码_基于jsp的婚庆网站-JavaEE实现婚庆网站 - java项目源码
- 修复steam服务器失败,steam服务器链接失败
- 如何在Golang中返回错误?