作一个积极的人java
编码、改bug、提高本身git
我有一个乐园,面向编程,春暖花开!程序员
推荐阅读面试
第一季
0、Java的线程安全、单例模式、JVM内存结构等知识梳理编程
一、Java内存管理-程序运行过程(一)设计模式
三、Java内存管理-JVM内存模型以及JDK7和JDK8内存模型对比总结(三)缓存
七、Java内存管理-掌握自定义类加载器的实现(七)
第一季总结:由浅入深JAVA内存管理 Core Story第二季
九、Java内存管理-”一文掌握虚拟机建立对象的秘密”(九)
十、Java内存管理-你真的理解Java中的数据类型吗(十)
十一、Java内存管理-Stackoverflow问答-Java是传值仍是传引用?(十一)
十二、Java内存管理-探索Java中字符串String(十二)
实战
分享一位老师的人工智能教程。零基础!通俗易懂!风趣幽默!你们能够看看是否对本身有帮助,点击这里查看【人工智能教程】。接下来进入正文。
勿在流沙筑高台,出来混早晚要还的。
做为Java程序员,Java 的数据类型这个是必定要知道的! 可是无论是那种数据类型最终存储都要到内存中,本文由浅入深对数据类型进行介绍和讲解,相信读完本文你必定会有收获的,会对Java数据类型有更深的了解和认识!
本文地图
位(bit):计算机内部存储数据的最小单位,音译为比特,每一个二进制数字0或者1就是1个位!
字节(Byte):计算机存储容量(数据处理)的基本单位,音译拜特,8个位构成一个字节;即:1 byte (字节)= 8 bit(位)。
一个字节可以存放的数字范围用二进制表示为000000000~11111111,也就是8个bit(比特),8个比特转换为无符号的10进制数字范围是0~255,转换为有符号数据通常为-128~127。
字节说明:对于存储容量,咱们是比较熟悉的,计算机存储容量大小以字节数来度量,1024进位制:
1024B=1K(千)B (1024个字节等于 1KB)
1024KB=1M(兆)B
1024MB=1G(吉)B
1024GB=1T(太)B
还有PB、EB、ZB、YB 、NB、DB等复制代码
字符:字符是一种符号,同以上说的存储单位不是一回事。指计算机中使用的字母、数字、字和符号,包括:一、二、三、A、B、C、~!·#¥%……—*()——+等等。字符通常在不一样的编码(字符集)下面占用的字节数不一样!也即占用存储空间不一样!
编码:编码就是一个编号(数字)到字符的一种映射关系(集合),常见的有 ASCII、ISO-8859-一、GB23十二、GBK、UTF-八、UTF-16 等。它们均可以被看做为字典,它们规定了转化的规则,按照这个规则就可让计算机正确的表示咱们的字符。
# 简单举例举例:
在 ASCII 编码中,一个英文字母字符存储须要1个字节。
在 GB 2312 编码或 GBK 编码中,一个汉字字符存储须要2个字节。
在UTF-8编码中,一个英文字母字符存储须要1个字节,一个汉字字符储存须要3到4个字节。
在UTF-16编码中,一个英文字母字符或一个汉字字符存储都须要2个字节(Unicode扩展区的一些汉字存储须要4个字节)。
在UTF-32编码中,世界上任何字符的存储都须要4个字节。复制代码
tips:
ASCII码是最熟知字符编码,编码范围为0~255,属于单字节编码。ASCII码编码范围过小了,Java为了可以处理多字节语言编码(好比中文、日文、韩文等)编码范围0x000000~0x10FFFF,采用国际组织制定的Unicode编码集。
由于Unicode编码并不是连续的,全部将Unicode转换为具体的数值格式是又有多种不一样的转换方式。称为Unicode Translation Format(UTF)。
简单总结一下UTF-八、UTF-1六、UTF-32三种转换方式,都是采用字节做为编码的基本单位!
转换方式 | 特色 |
优势 |
缺点 |
---|---|---|---|
UTF-8 |
变长编码,1-4字节 | 节省空间 |
转换麻烦 |
UTF-16 |
固定编码,2字节 |
转换相对简单 | 空间相对节省 |
UTF-32 |
固定编码,4字节 |
转换简单 |
空间最浪费 |
目前使用UTF-8仍是比较多,节省空间仍是很大的优点! 在说明一点Java虚拟机内部使用的UTF-16转换方式,固定使用两个字节,因此java中字符char 占用 2个字节!
编码这一块的内容其实挺多,如需了解更多深刻细节,请自行查阅相关资料!
有学过C语言的伙伴知道在C语言中能够声明指针类型的变量,可是在Java语言中是看不到使用指针的,那么Java中有没有指针呢?准确的话是有的,由于在Java底层有些类型是封装了指针的。在Java中根据底层是否封装了指针能够将Java的数据类型分为两类,值类型和引用类型!
值类型: 也称为基本数据类型和基元数据类型。它的值就是一个数字,一个字符或一个布尔值等。
没有封装指针的变量,它们在Java中有8个,包括byte
、char
、 short
、int
、float
、long
、double
、boolean
。
这些基本类型首字母都是小写,它们并非类,也没有属性和方法。声明值类型变量,只会在栈中分配一块内存空间。
这里面还有一个知识点是: 自动类型转换和强制类型转换!
自动类型转换:
通常状况下Java中会将占用内存空间较低的类型转换为较高类型,如 int型的变量和 long型的变量进行计算的时候,会将int型转换为long型;
若是两个变量占用内存空间同样,可是一个是整型,一个是浮点型,则会将整型转换为浮点型。如int型变量与float型变量进行计算,会将int型转换为float型。
强制类型转换:
第一种状况:提高变量的类型级别,以获取精度更高的计算结果! 好比 两个整型int变量进行除法运算,为了精度更高,强制转为long类型!
第二种状况:须要用占用空间较小的变量类型接受占用空间较大的变量类型。好比 int转为byte等,可是要注意 转换过程当中产生溢出截断的状况!
上面图中内容中没有boolean类型变量进行说明,由于boolean类型比较特殊。boolean类型变量只有两个值,true或者false,它不参与数学运算,也不能与其余类型变量进行转换(无论自动转换仍是强制转换),只是用来进行逻辑判断。
boolean类型变量的内存空间占用具备必定的不肯定性,理论上一个比特就能够保存boolean类型变量的值,当由于内存使用的最小单位是字节,那么变量不可能仅占用1/8个字节。实际中,根据编译器的不一样,Java会使用1~4字节来保存boolean变量。字节内容均为0表示false。只要有字节为非0值表示true。
面试必定要注意 :String 不是基本类型!
引用类型: 就是底层封装指针的数据类型。这部分包含的比较多,好比咱们自定义或者系统的类、抽象类、接口,以及数组。它们在内存中分配两块空间,首先要在栈上给其引用(句柄)分配一块内存(不存放具体数值),而后对象的具体信息都存储在堆内存上(如对象的属性值等),最后由栈上面的引用指向堆中对象的地址。
示例代码:
public class PrettyGirl {
/**
* 姑娘姓字名谁
*/
String name;
/**
* 芳龄几何
*/
int age;
public static void main(String[] args) {
// PrettyGirl是自定义类,是引用类型,分配两块内存空间
PrettyGirl prettyGirl = new PrettyGirl();
// String类是系统类,也是引用类型,分配两块内存空间
String name = new String("Java ok");
// int,float 是值类型,只分配一块内存空间
int num = 10;
float price = 110.10f;
// 对象名.属性名访问对象的属性,访问包括赋值和取值
prettyGirl.name = "Alice";
prettyGirl.age = 25;
}
}复制代码
经过类名 对象名 = new 类名()建立对象
, 在 PrettyGirl prettyGirl = new PrettyGirl();
这行代码在内存中就建立了两块内存空间,第一块在栈中,名字叫 prettyGirl
,它是一个引用地址,并不放具体的数值,第二块堆中的内存才存放具体的数值,如name,age等信息。
其实数组内部也是封装引用(指针),即使是基本类型的数组,也是如此! 数组也是引用类型!好比
int[] nums = new int[]{1,4,7,3,9};复制代码
说明 :0x001 是我随便写的一个值,真实的内存地址并非这个,这个值只是为了我画图方便!
在多强调一点,在引用类型中,对于类来讲,要建立对象其实包括两步,第一是声明对象,第二是建立对象!
public static void main(String[] args) {
// 声明对象,至关分配指针类型变量,在栈中分配内存
PrettyGirl alice;
// 建立对象,建立具体内存空间,在堆中分配内存
alice = new PrettyGirl();
}复制代码
声明对象:就至关于在栈中声明引用类型的变量,它的内存不存放具体的数值,而只存放另外一块堆中内存的地址!如
PrettyGirl alice;复制代码
建立对象:通常使用new关键字,以下代码
alice = new PrettyGirl();复制代码
上面这一行代码作了两件事情,首先在堆中分配一块存放具体数值的内存,而后将这个内存的首地址赋给上面声明的引用变量!
其实不少时候,对象的声明和建立是放在一行的,以下:
PrettyGirl mary = new PrettyGirl();复制代码
如下内容摘自:参考资料1 中 8种基本类型的包装类和常量池部份内容!
Java 基本类型的包装类的大部分都实现了常量池技术,即Byte,Short,Integer,Long,Character,Boolean;这5种包装类默认建立了数值[-128,127]的相应类型的缓存数据,可是超出此范围仍然会去建立新的对象。
两种浮点数类型的包装类 Float,Double 并无实现常量池技术。
Integer i1 = 33;
Integer i2 = 33;
System.out.println(i1 == i2);// 输出true
Integer i11 = 333;
Integer i22 = 333;
System.out.println(i11 == i22);// 输出false
Double i3 = 1.2;
Double i4 = 1.2;
System.out.println(i3 == i4);// 输出false, 无缓存!复制代码
Integer 缓存源代码:
/**
*此方法将始终缓存-128到127(包括端点)范围内的值,并能够缓存此范围以外的其余值。
*/
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}复制代码
对于Integer类型来讲,值在-128-127,用==比较是一致的,超过这个区间就不行了。
应用场景:
Integer i1 = 40;
Integer i2 = new Integer(40);
System.out.println(i1==i2);//输出false复制代码
最后在贴出阿里巴巴Java手册中对包装类使用的建议:
本文总体内容相对基础,可是在java开发中仍是很是重要,注重细节和基础,让写出的每一行代码都是最优的!朝着这个方向努力! 下一篇整理一下值传递和引用传递! 敬请期待!
备注: 因为本人能力有限,文中如有错误之处,欢迎指正。
谢谢你的阅读,若是您以为这篇博文对你有帮助,请点赞或者喜欢,让更多的人看到!祝你天天开心愉快!