Java基本类型和包装类型总结
1.Java的基本类型及其对应的包装器类
Java有8种基本类型:大致分为3类:字符,布尔,数值类型(在java中数值是不存在无符号的,这一点不像C/C++,他们的取值范围是固定的,不会随着机器硬件的环境或者操作系统的改变而改变)
- byte:8位,最大存储数据量是255,存放的数据范围是-128~127之间。
- short:16位,最大数据存储量是65536,数据范围是-32768~32767之间。
- int:32位,最大数据存储容量是2的32次方减1,数据范围是负的2的31次方到正的2的31次方减1。
- long:64位,最大数据存储容量是2的64次方减1,数据范围为负的2的63次方到正的2的63次方减1。
- float:32位,数据范围在3.4e-45~1.4e38,直接赋值时必须在数字后加上f或F。
- double:64位,数据范围在4.9e-324~1.8e308,赋值时可以加d或D也可以不加。
- boolean:只有true和false两个取值。
1.Java决定了每种简单类型的大小。这些大小并不随着机器结构的变化而变化。这种大小的不可更改正是Java程序具有很强移植能力的原因之一。下表列出了Java中定义的简单类型、占用二进制位数及对应的封装器类。
基本类型 | 二进制位数 | 包装器类 |
---|---|---|
boolean | 1 | Boolean |
byte | 8 | Byte |
char | 16 | Character |
short | 16 | Short |
int | 32 | Integer |
long | 64 | Long |
float | 32 | Float |
double | 64 | Double |
2.对于取值范围,在对应的包装器类中有常量记载,直接调用就可以了,无需记忆
- 基本类型byte 二进制位数:Byte.SIZE最小值:Byte.MIN_VALUE最大值:Byte.MAX_VALUE
- 基本类型short二进制位数:Short.SIZE最小值:Short.MIN_VALUE最大值:Short.MAX_VALUE
- 基本类型char二进制位数:Character.SIZE最小值:Character.MIN_VALUE最大值:Character.MAX_VALUE
- 基本类型double 二进制位数:Double.SIZE最小值:Double.MIN_VALUE最大值:Double.MAX_VALUE
Java基本类型存储在栈中,因此它们的存取速度要快于存储在堆中的对应包装类的实例对象。从Java5.0(1.5)开始,JAVA虚拟机(Java Virtual Machine)可以完成基本类型和它们对应包装类之间的自动转换。因此我们在赋值、参数传递以及数学运算的时候像使用基本类型一样使用它们的包装类,但这并不意味着你可以通过基本类型调用它们的包装类才具有的方法。另外,所有基本类型(包括void)的包装类都使用了final修饰,因此我们无法继承它们扩展新的类,也无法重写它们的任何方法。
3.基本类型出现的原因
在Java编程思想的第一章就讲到:万物皆对象,new一个对象存储在堆中,我们通过堆栈的引用来使用这些对象,但是对于经常用到的一系列类型如int,如果我们用new将其存储在堆里就不是很有效——特别是简单的小的变量。所以就出现了基本类型,同C++一样,Java采用了相似的做法,对于这些类型不是用new关键字来创建,而是直接将变量的值存储在堆栈中,因此更加高效。
4.包装类型出现的原因
Java是一个面向对象的语言,基本类型并不具有对象的性质,为了与其他对象“接轨”就出现了包装类型(如我们在使用集合类型Collection时就一定要使用包装类型而非基本类型),它相当于将基本类型“包装起来”,使得它具有了对象的性质,并且为其添加了属性和方法,丰富了基本类型的操作。
5.关于基本类型和包装类型的总结
- 基本类型的优势:数据存储相对简单,运算效率比较高
- 包装类的优势:有的容易,比如集合的元素必须是对象类型,满足了java一切皆是对象的思想
- 声明方式不同,基本类型不适用new关键字,而包装类型需要使用new关键字来在堆中分配存储空间;
- 存储方式及位置不同,基本类型是直接将变量值存储在堆栈中,而包装类型是将对象放在堆中,然后通过引用来使用;
- 初始值不同,基本类型的初始值如int为0,boolean为false,而包装类型的初始值为null
- 使用方式不同,基本类型直接赋值直接使用就好,而包装类型在集合如Collection、Map时会使用到
2.Java类型转换
- 1.自动转换
- 2.强制转换
- 3.包装器过渡类型转换
- 4.字符串与其他类型之间的转换
- 5.Date和其他数据类型之间的转换
import java.text.SimpleDateFormat;
import java.util.Date;public class Demo01 {/*** @param args*/public static void main(String[] args) {// TODO Auto-generated method stub//1.自动转换byte b1 = 12;int a = b1*2; //这里发生了自动转换//2.强制转换测试byte byte1 = 12;byte byte2 = 1;byte i =(byte)(byte1 + byte1); //显示不能从byte转换成int 这里需要强制转换//3.包装器过渡转换String s = "123";int value = Integer.parseInt(s); //方法返回int值赋给value//4.字符串和其他类型的转换int num = 2017;String time= ""+num; //右边最终结果是StringString str1 = "123";int value1 = Integer.valueOf(str1); //结果是int 123//5.Date与其他数据类型的相互转换Date date = new Date(); SimpleDateFormat format = new SimpleDateFormat("yyyyMMDD");String timeString = format.format(date);}}
总结:只有boolean不参与数据类型的转换
- (1).自动类型的转换:
a.常数在表数范围内是能够自动类型转换的
b.数据范围小的能够自动数据类型大的转换(注意特例)int到float,long到float,long到double 是不会自动转换的,不然将会丢失精度
c.引用类型能够自动转换为父类的
d.基本类型和它们包装类型是能够互相转换的
- (2).强制类型转换:用圆括号括起来目标类型,置于变量前
3.Java引用类型
Java有 5种引用类型(对象类型):类 接口 数组 枚举 标注
引用类型:底层结构和基本类型差别较大
JVM的内存空间:
(1). Heap 堆空间:分配对象 new Student()
(2). Stack 栈空间:临时变量 Student stu
(3).Code 代码区 :类的定义,静态资源 Student.class
Student stu = new Student(); //new 在内存的堆空间创建对象
stu.study(); //把对象的地址赋给stu引用变量
上例实现步骤:
a.JVM加载Student.class 到Code区
b.new Student()在堆空间分配空间并创建一个Student实例
c.将此实例的地址赋值给引用stu, 栈空间
4.Java包装类的一些常见知识点归纳
- 1.Java包装器比较大小(很有意思的问题)
public static void main(String[] args) {Integer a = new Integer(100);Integer b = new Integer(100);/* compareTo返回值:若a>b则返回1;若a==b则返回0;若a<b则返回-1 */int result = a.compareTo(b);System.out.println(a > b);System.out.println(a == b);System.out.println(a > b);System.out.println(result);
}
运行结果:
false
false
false
0
为什么(a==b)返回值会是false呢?
通过对比字符串比较来理解,基本类型100通过包装类Integer包装后生产一个Integer对象的引用a,而“==”使用来判断两个操作数是否有相等关系。如果是基本类型就直接判断其值是否相等。若是对象就判断是否是同一个对象的引用,显然我们new了两个不同的对象。但注意:对于”<”,”>” 只是用来判断两个基本类型的数值的大小关系。在进行”(a < b)运算时,实际上是根据其 intValue方法的返回对应的数值来进行比较的。因此返回肯定是false.
知道问题原因,解决起来就容易了。两种方法:
第一种: a.intValue()==b.intValue();
第二种: a.compareTo(b);//返回-1代码(a
public int compareTo(Integer object) {int thisValue = value;int thatValue = object.value;return thisValue < thatValue ? -1 : (thisValue == thatValue ? 0 : 1);
}
- 2.Java包装类常量池
Java的8种基本类型(Byte, Short, Integer, Long, Character, Boolean, Float, Double), 除Float和Double以外, 其它六种都实现了常量池, 但是它们只在大于等于-128并且小于等于127时才使用常量池。
public static void main(String[] args) { //常量池的测试System.out.println("Integer的测试");Integer a = 127; Integer b = 127; System.out.println(a == b); a = 128; b = 128; System.out.println(a == b); a = -128; b = -128; System.out.println(a == b); a = -129; b = -129; System.out.println(a == b); // 测试Boolean System.out.println("测试Boolean"); Boolean c = true; Boolean d = true; System.out.println(c == d); d = new Boolean(true); System.out.println(c == d);
}
程序运行结果
Integer的测试
true
false
true
false
测试Boolean
true
false
当我们给Integer赋值时,实际上调用了Integer.valueOf(int)方法(编译期进行装箱),查看源码,其实现如下:
public static Integer valueOf(int i) { if(i >= -128 && i <= IntegerCache.high) return IntegerCache.cache[i + 128]; else return new Integer(i);
}
而IntegerCache实现如下
private static class IntegerCache { static final int high; static final Integer cache[]; static { final int low = -128; // high value may be configured by property int h = 127; if (integerCacheHighPropValue != null) { // Use Long.decode here to avoid invoking methods that // require Integer's autoboxing cache to be initialized int i = Long.decode(integerCacheHighPropValue).intValue(); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(i, Integer.MAX_VALUE - -low); } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); } private IntegerCache() {}
}
注意cache数组是静态的。
下面的语句不会缓存常量:
Integer integer = new Integer(127);
因为使用了new关键字,一定是创建了一个新的对象,无法进行缓存优化。
- 3.Java基本类型和包装类型使用运算符 == 进行比较的底层细节? 是引用还是至比较值?
public class IntegerCompareTest {/*** @param args*/public static void main(String[] args) {// TODO Auto-generated method stubObject obj = new Integer(1024); if(Integer.valueOf(obj.toString())==1024){ System.out.println("Integer.valueOf(obj.toString())==1024 is true"); } }
}
通过Javap.exe进行反编译得到的JVM指令如下所示
Classfile /C:/Users/JIN/Documents/GitHub/JavaBasePractice/bin/com/jinwen/basetype/IntegerCompareTest.classLast modified 2017-7-19; size 906 bytesMD5 checksum d0968e0c73408dd3cb83daddfe8e1a1bCompiled from "IntegerCompareTest.java"
public class com.jinwen.basetype.IntegerCompareTestSourceFile: "IntegerCompareTest.java"minor version: 0major version: 50flags: ACC_PUBLIC, ACC_SUPERConstant pool:#1 = Class #2 // com/jinwen/basetype/IntegerCompareTest#2 = Utf8 com/jinwen/basetype/IntegerCompareTest#3 = Class #4 // java/lang/Object#4 = Utf8 java/lang/Object#5 = Utf8 <init>#6 = Utf8 ()V#7 = Utf8 Code#8 = Methodref #3.#9 // java/lang/Object."<init>":()V#9 = NameAndType #5:#6 // "<init>":()V#10 = Utf8 LineNumberTable#11 = Utf8 LocalVariableTable#12 = Utf8 this#13 = Utf8 Lcom/jinwen/basetype/IntegerCompareTest;#14 = Utf8 main#15 = Utf8 ([Ljava/lang/String;)V#16 = Class #17 // java/lang/Integer#17 = Utf8 java/lang/Integer#18 = Methodref #16.#19 // java/lang/Integer."<init>":(I)V#19 = NameAndType #5:#20 // "<init>":(I)V#20 = Utf8 (I)V#21 = Methodref #3.#22 // java/lang/Object.toString:()Ljava/lang/String;#22 = NameAndType #23:#24 // toString:()Ljava/lang/String;#23 = Utf8 toString#24 = Utf8 ()Ljava/lang/String;#25 = Methodref #16.#26 // java/lang/Integer.valueOf:(Ljava/lang/String;)Ljava/lang/Integer;#26 = NameAndType #27:#28 // valueOf:(Ljava/lang/String;)Ljava/lang/Integer;#27 = Utf8 valueOf#28 = Utf8 (Ljava/lang/String;)Ljava/lang/Integer;#29 = Methodref #16.#30 // java/lang/Integer.intValue:()I#30 = NameAndType #31:#32 // intValue:()I#31 = Utf8 intValue#32 = Utf8 ()I#33 = Fieldref #34.#36 // java/lang/System.out:Ljava/io/PrintStream;#34 = Class #35 // java/lang/System#35 = Utf8 java/lang/System#36 = NameAndType #37:#38 // out:Ljava/io/PrintStream;#37 = Utf8 out#38 = Utf8 Ljava/io/PrintStream;#39 = String #40 // Integer.valueOf(obj.toString())==1024 is true#40 = Utf8 Integer.valueOf(obj.toString())==1024 is true#41 = Methodref #42.#44 // java/io/PrintStream.println:(Ljava/lang/String;)V#42 = Class #43 // java/io/PrintStream#43 = Utf8 java/io/PrintStream#44 = NameAndType #45:#46 // println:(Ljava/lang/String;)V#45 = Utf8 println#46 = Utf8 (Ljava/lang/String;)V#47 = Utf8 args#48 = Utf8 [Ljava/lang/String;#49 = Utf8 obj#50 = Utf8 Ljava/lang/Object;#51 = Utf8 StackMapTable#52 = Utf8 SourceFile#53 = Utf8 IntegerCompareTest.java
{public com.jinwen.basetype.IntegerCompareTest();flags: ACC_PUBLICCode:stack=1, locals=1, args_size=10: aload_0 1: invokespecial #8 // Method java/lang/Object."<init>":()V4: return LineNumberTable:line 3: 0LocalVariableTable:Start Length Slot Name Signature0 5 0 this Lcom/jinwen/basetype/IntegerCompareTest;public static void main(java.lang.String[]);flags: ACC_PUBLIC, ACC_STATICCode:stack=3, locals=2, args_size=10: new #16 // class java/lang/Integer3: dup 4: sipush 10247: invokespecial #18 // Method java/lang/Integer."<init>":(I)V10: astore_1 11: aload_1 12: invokevirtual #21 // Method java/lang/Object.toString:()Ljava/lang/String;15: invokestatic #25 // Method java/lang/Integer.valueOf:(Ljava/lang/String;)Ljava/lang/Integer;18: invokevirtual #29 // Method java/lang/Integer.intValue:()I21: sipush 102424: if_icmpne 3527: getstatic #33 // Field java/lang/System.out:Ljava/io/PrintStream;30: ldc #39 // String Integer.valueOf(obj.toString())==1024 is true32: invokevirtual #41 // Method java/io/PrintStream.println:(Ljava/lang/String;)V35: return LineNumberTable:line 10: 0line 11: 11line 12: 27line 14: 35LocalVariableTable:Start Length Slot Name Signature0 36 0 args [Ljava/lang/String;11 25 1 obj Ljava/lang/Object;StackMapTable: number_of_entries = 1frame_type = 252 /* append */offset_delta = 35locals = [ class java/lang/Object ]}
分析:code的标号15:确实是调用静态的valueOf方法解析字符串为Integer实例,但其后标号18:有调用了Integer实例的intValue()方法返回了该实例相应的int值,从而最后比较的实际是int和int进行比较,所以比较结果是true;
通过上述分析可以确定 “包装对象==相应值” 这样的比较是可行的,但却不是推荐的。因为解析String实例为Integer实例,然后在去Integer实例里面去取的int值进行比较,在此Integer实例就多此一举了,还不如直接使用parseInt解析字符为相应的int值直接进行比较,节省创建一个Integer实例所浪费的资源。
Java基本类型和包装类型总结相关推荐
- java基本类型和包装类型
java是面向对象的语言为什么还要有基本类型,只有包装类型完全面向对象不行吗? java语言可以只有基本类型吗,为什么还有要包装类型? java中的基本类型和包装类型: 基本类型 包装器类 ...
- java基本类型和包装类型的区别
1.为什么存在基本类型: 在Java中正常应该设置对象,然后通过new一个对象存储在堆中,再通过栈的引用来使用对象,但对于简单的小的变量,用new 显的繁琐麻烦,所以产生了基本类型 2.有了基本类型, ...
- java的包装类型是什么用_Java基本类型和包装类型的区别
包装类型可以为 null,而基本类型不可以 别小看这一点区别,它使得包装类型可以应用于 POJO 中,而基本类型则不行. POJO 是什么呢?这里稍微说明一下. POJO 的英文全称是 Plain O ...
- 基本类型和包装类型的区别详解
六年前,我从苏州回到洛阳,抱着一幅"海归"的心态,投了不少简历,也"约谈"了不少面试官,但仅有两三个令我感到满意.其中有一位叫老马,至今还活在我的手机通讯录里. ...
- CSDN日报190929:面试官:兄弟,说说基本类型和包装类型的区别吧
CSDN日报来啦!给大家奉上当日最新鲜的技术干货! 深度学习|[深度学习] 自然语言处理-Attention 作者:小墨鱼~~ 要了解深度学习中的注意力模型,就不得不先谈Encoder-Decoder ...
- 包装类型是什么?基本类型和包装类型有什么区别?
Java 为每一个基本数据类型都引入了对应的包装类型(wrapper class),int 的包装类就是 Integer,从 Java 5 开始引入了自动装箱/拆箱机制,把基本类型转换成包装类型的过程 ...
- 基本类型和包装类型的区别
1.基本类型有初始值,而包装类型的默认值是null 数据类型 默认值 byte 0 short 0 int 0 long 0L float 0.0f double 0.0d char '/u0000' ...
- 【Java】浅析八种基本类型和包装类型
Java八种基本类型 <Java八种基本类型分析> Java基本类型对应的包装类 Everything is object Java编程语言不把基本数据类型看作对象.Java 编程语言提供 ...
- java基本类型和封装类型区别及应用
1.基本类型只能按值传递,而每个基本类型对应的封装类是按引用传递的. 2.从性能上说java中的基本类型是在堆栈上创建的,而所有的对象类型都是在堆上创建的,(对象的引用在堆栈上创建).比如 Int ...
最新文章
- 铜陵新松工业机器人项目_投资10亿元,茶山德威工业机器人和精密模具项目动工...
- pandas分层索引(层级索引、MultiIndex)的创建、取值、切片、统计计算以及普通索引和层级索引的转换方法
- 趣事:一根网线发起的攻击
- [转载]永远保持随时可以离开的能力(不仅仅是张泉灵)
- python语言名片管理系统,进行增删改查
- jdk说明文档_给JDK报了一个P4的Bug,结果居然……
- Spring AOP之概念解释
- 【.md格式文件编辑器】几款主流好用的markdown编辑器介绍
- cad化工设备绘图_化工设备CAD绘图技巧
- 乐鑫Esp32学习之旅30 对接华为IoT物联网平台适配踩坑,使用ESP-IDF 编程使用HTTPS请求固件跳过证书校验,实现OTA远程升级文件。(附带源码)
- 单细胞转录组测序和空间转录组学
- PYTHON Fraction 分数处理
- Python实现Word表格转成Excel表格
- Spring(二)--------Spring配置、DI依赖注入、Bean自动装配
- 细数红帽linux系统下的各个文件夹作用
- jetson-nano环境查询
- bom成本分析模型_BOM成本估算表
- 今年Java面试必问的这些技术面,完整版开放免费下载!
- ChatGPT原理解析以及使用方法介绍
- Xing: The Land Beyond — 从课堂到 Steam* 的卓越之旅