java基本数据类型及其封装类
Nov 30, 2017
之前刚从python写java,碰到过两个String比较大小,习惯性用了“==”,发现不管我的String赋什么样的值,最后都是false。后来网上搜了一下,发现是封装类的原因。
1.相关说明
说到封装类,不得不提到栈内存和堆内存。
堆内存在Java运行时被使用来为对象和JRE类分配内存。不论什么时候我们创建了对象,它将一直会在堆内存上创建。垃圾回收运行在堆内存上来释放没有任何引用的对象所占的内存,任何在堆上被创建的对象都有一个全局的访问,并且可以在应用的任何位置被引用。
Java的栈内存被用来线程的执行,他们包含生命周期很短的具体值的方法和在堆中使用这个方法对象的引用。栈内存是LIFO(后进先出)序列。当方法被调用的时候,堆内存中一个新的块被创建,保存了本地原始值和在方法中对其他对象的引用。这个方法结束之后,这个块对其他方法就变成可用的了。和堆内存比,栈内存要小的多,因为明确使用了内存分配规则(LIFO),和堆内存相比栈内存非常快。
2. 封装类型和基本类型比较
2.1 封装类型和基本类型说明
Java的基本数据类型:int,double,float,long,byte,char,boolean。
对应的封装类:Integer,Double,Float,Long,Byte,Char,Boolean。
封装类型和基本类型的内存模型本质上是不一样的。基本数据类型直接存储在内存中的内存栈上的,数据本身的值就是存储在栈空间里面,不存在“引用”的概念。封装类型是按照Java里面存储对象的内存模型来进行数据存储的,使用Java内存堆和内存栈来进行这种类型的数据存储,对象本身的值存储在内存堆上,栈内存只包含原始值变量和堆中对象变量的引用。封装类型和基本类型有不同的默认值:封装类型默认值为null,基本类型的默认值于本身的类型有关。基本数据类型本身就是一个值。
2.2基本数据类型及其封装类的转换
定义基本数据类型转封装类:
|
|
在添加了自动装拆箱的功能之后:
|
|
封装类转基本数据类型:
|
|
当然,也可以直接int num=integer,这里的自动拆箱,其实也是调用了封装类的intValue()方法来实现的。
将String类型字符串与基本数据类型进行转换。
字符串转基本数据类型:
|
|
基本数据类型转字符串:
|
|
封装类转字符串,直接调用封装类对象的toString()方法即可。
|
|
2.3 封装类型和基本类型数值直接的比较方法(equal和==)
例如:
|
|
变量n和变量m都是直接存储的“3”这个数值,所以用==比较的时候结果是true。
而对于非基本数据类型的变量,是引用类型的变量,引用类型的变量存储的并不是“值”本身,而是于其关联的对象在内存中的地址。例如:
|
|
这句话声明了一个引用类型的变量,此时它并没有和任何对象关联。
而通过newString(”hello”)来产生一个对象(也称作为类String的一个实例),并将这个对象和str1、str2进行绑定:
|
|
那么str1指向了一个对象,此时变量str1中存储的是它指向的对象在内存中的存储地址,并不是“值”本身,也就是说并不是直接存储的字符串”hello”。这里面的引用和C/C++中的指针很类似。
因此在用==对str1和str2进行第一次比较时,得到的结果是false。因此它们分别指向的是不同的对象,也就是说它们实际存储的内存地址不同。
而在第二次比较时,都让str1和str2指向了str指向的对象,那么得到的结果毫无疑问是true。
equals方法是基类Object中的方法,因此对于所有的继承于Object的类都会有该方法。
在Object类中,equals方法是用来比较两个对象的引用是否相等,即是否指向同一个对象。String类对equals方法进行了重写,用来比较指向的字符串对象所存储的字符串是否相等。
对于封装过之后,每个类型都有对应的缓存:
| 类型 | 缓存情况 |
|---|---|
| Byte | 全部缓存 |
| Boolean | 全部缓存 |
| Integer | -128~127缓存 |
| Character | <=127缓存 |
| Short | -128~127缓存 |
| Long | -128~127缓存 |
| Float | 没有缓存 |
| Double | 没有缓存 |
例如:
|
|
对于-128到127之间的数,会进行缓存,Integer i1=127时,会将127进行缓存,下次再写Integer i2=127时,就会直接从缓存中取,就不会new了。所以i1 == i2 是true;而_i1 == _i2是false。
3.总结
3.1基本类型:
优点:
- 用于计算效率高
- 不会由于常量池引起比较大小错误
缺点:
- 当数据库中查询出结果之后封装结果集时如果返回的值时null时,如果直接赋值给这个基本类型的字段时,会在运行时报出异常,不能将null赋给一个基本类型,而用Integer就不存在这样都的情况
- 当用spring的表单对象时如果页面传来的值是只有字段没有值是如果表单对象中有基本类型的值时会抛出异常。需要设置在数据库中为该字段设置默认值,但是这经常会被忽略。
3.2封装类型
优点:
- 可以存放null,从数据库中查出值时可能会有null
- 表示一个值(不用于计算,只用于保存值时和int类型一样);
缺点
- 不能用于两个Integer对象双等判断两个对象的值相等,会出现错误的。
java中Integer,String判断相等与integer的比较大小不适合频繁的用于计算,要用双等判断两个对象的值是否相等时,要调用intValue方法
综上所述,在建立实体类时,用封装类型比较好;如果需要频发的计算,则用基本类型效率更高。
