Java内存管理-你真的理解Java中的数据类型吗(十)
勿在流沙筑高台,出来混迟早要还的。
做一个积极的人
编码、改bug、提升自己
我有一个乐园,面向编程,春暖花开!
作为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等
字符:字符是一种符号,同以上说的存储单位不是一回事。指计算机中使用的字母、数字、字和符号,包括:1、2、3、A、B、C、~!·#¥%……—*()——+等等。字符一般在不同的编码(字符集)下面占用的字节数不同!也即占用存储空间不同!
编码:编码就是一个编号(数字)到字符的一种映射关系(集合),常见的有 ASCII、ISO-8859-1、GB2312、GBK、UTF-8、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-8、UTF-16、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的数据类型分为两类,值类型和引用类型!
2.1、值类型
值类型: 也称为基本数据类型和基元数据类型。它的值就是一个数字,一个字符或一个布尔值等。
没有封装指针的变量,它们在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 不是基本类型!
2.2、引用类型
引用类型: 就是底层封装指针的数据类型。这部分包含的比较多,比如我们自定义或者系统的类、抽象类、接口,以及数组。它们在内存中分配两块空间,首先要在栈上给其引用(句柄)分配一块内存(不存放具体数值),然后对象的具体信息都存储在堆内存上(如对象的属性值等),最后由栈上面的引用指向堆中对象的地址。
2.3、简单示例
示例代码:
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 是我随便写的一个值,真实的内存地址并不是这个,这个值只是为了我画图方便!
在多强调一点,在引用类型中,对于类来说,要创建对象其实包括两步,第一是声明对象,第二是创建对象!
```java public static void main(String[] args) { // 声明对象,相当分配指针类型变量,在栈中分配内存 PrettyGirl alice; // 创建对象,创建具体内存空间,在堆中分配内存 alice = new PrettyGirl(); }
声明对象:就相当于在栈中声明引用类型的变量,它的内存不存放具体的数值,而只存放另一块堆中内存的地址!如
java PrettyGirl alice;
创建对象:一般使用new关键字,如下代码
java alice = new PrettyGirl();
上面这一行代码做了两件事情,首先在堆中分配一块存放具体数值的内存,然后将这个内存的首地址赋给上面声明的引用变量!
![](http://dufyun.gitee.io/images_bed/images/techy/JVM10-07.png)
其实很多时候,对象的声明和创建是放在一行的,如下:
java PrettyGirl mary = new PrettyGirl();
## 三、 八种基本类型的包装类和常量池
以下内容摘自:参考资料1 中 8种基本类型的包装类和常量池部分内容!
Java 基本类型的包装类的大部分都实现了常量池技术,即Byte,Short,Integer,Long,Character,Boolean;**这5种包装类默认创建了数值[-128,127]的相应类型的缓存数据,但是超出此范围仍然会去创建新的对象**。
**两种浮点数类型的包装类 Float,Double 并没有实现常量池技术。**
java 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 缓存源代码:**
java /** *此方法将始终缓存-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,用==比较是一致的,超过这个区间就不行了。
**应用场景:**
1. Integer i1=40;Java 在编译的时候会直接将代码封装成Integer i1=Integer.valueOf(40);,从而使用常量池中的对象。
2. Integer i1 = new Integer(40);这种情况下会创建新的对象。
java Integer i1 = 40; Integer i2 = new Integer(40); System.out.println(i1==i2);//输出false ```
最后在贴出阿里巴巴Java手册中对包装类使用的建议:
四、本文总结
本文整体内容相对基础,但是在java开发中还是非常重要,注重细节和基础,让写出的每一行代码都是最优的!朝着这个方向努力! 下一篇整理一下值传递和引用传递! 敬请期待!
五、参考资料
谢谢你的阅读,如果您觉得这篇博文对你有帮助,请点赞或者喜欢,让更多的人看到!祝你每天开心愉快!
不管做什么,只要坚持下去就会看到不一样!在路上,不卑不亢!
博客首页 : http://blog.csdn.net/u010648555
愿你我在人生的路上能都变成最好的自己,能够成为一个独挡一面的人
© 每天都在变得更好的阿飞云
Java内存管理-你真的理解Java中的数据类型吗(十)的更多相关文章
- Java内存管理的进一步理解-模拟过程图解
Java内存管理的进一步理解-模拟过程图解--转载 java的内存管理分为: 1.堆内存:2.栈内存:3.方法区:4.本地方法区 /* 1:方法区 方法区存放装载的类数据信息包括: ...
- Java内存管理(一):深入Java内存区域
本文转自:http://www.cnblogs.com/gw811/archive/2012/10/18/2730117.html#undefined 推荐查看原文,原文格式更好一些. 本文引用自:深 ...
- 揭开Java内存管理的面纱
前言 相对于C.C++这些高性能语言,Java有着让此类程序员羡慕的功能:内存自动管理.似乎这样,Java程序员不用再关心内存,也不用去了解相关知识.但结果真的是这样吗?特别对于我们这种Android ...
- Java 内存管理
java 内存管理机制 JAVA 内存管理总结 java 是如何管理内存的 Java 的内存管理就是对象的分配和释放问题.(两部分) 分配 :内存的分配是由程序完成的,程序员需要通过关键字 new 为 ...
- 简单的例子 关于Java内存管理的讲解
我想做的是,逐行读取文件,然后用该行的电影名去获取电影信息.因为源文件较大,readlines()不能完全读取所有电影名,所以我们逐行读取. 就这段代码,我想要在位置二处使用base64,然后结果呢? ...
- java内存管理机制
JAVA 内存管理总结 1. java是如何管理内存的 Java的内存管理就是对象的分配和释放问题.(两部分) 分配 :内存的分配是由程序完成的,程序员需要通过关键字new 为每个对象申请内存空间 ( ...
- java内存管理(堆、栈、方法区)
java内存管理 简介 首先我们要了解我们为什么要学习java虚拟机的内存管理,不是java的gc垃圾回收机制都帮我们释放了内存了吗?但是在写程序的过程中却也往往因为不懂内存管理而造成了一些不容易察觉 ...
- 浅析java内存管理机制
内存管理是计算机编程中的一个重要问题,一般来说,内存管理主要包括内存分配和内存回收两个部分.不同的编程语言有不同的内存管理机制,本文在对比C++和Java语言内存管理机制的不同的基础上,浅析java中 ...
- java基础(一):谈谈java内存管理与垃圾回收机制
看了很多java内存管理的文章或者博客,写的要么笼统,要么划分的不正确,且很多文章都千篇一律.例如部分地方将jvm笼统的分为堆.栈.程序计数器,这么分太过于笼统,无法清晰的阐述java的内存管理模型: ...
随机推荐
- Es6对象的扩展和Class类的基础知识笔记
/*---------------------对象的扩展---------------------*/ //属性简写 ,属性名为变量名, 属性值为变量的值 export default functio ...
- 《剑指offer》 调整数组顺序使得奇数在偶数前面
本题来自<剑指offer> 调整数组顺序使得奇数在偶数前面 题目: 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分, ...
- laravel 实现一个简单的 RESTful API
创建一个 Article 资源 php artisan make:resource Article 你可以在 app/Http/Resources 目录下看到你刚刚生成的 Article 资源 当然我 ...
- poj2728 生成树01分数规划 (二分答案)
给定整数序列a,b,求出下式的最大值 sum{ai*xi}/sum{bi*xi},xi=0|1 通俗来说,就是选出一些整数对(ai,bi),使得选出的a之和与选出的b之和商最大化 二分答案L,即选出的 ...
- bzoj 2761
神题... 其实这题巨水,用各种诡异的方法都能A,包括STL等等 我之所以写题解,是因为我发现了一个bug:bz和luogu时限有问题! 这题我用了两种做法: ①:直接使用STL-map(不能直接用数 ...
- Git使用二:git与svn的区别与工作流程
svn记录的是每一次版本变动的内容,三角形代表改动的内容 git是将每个版本独立保存 git的三棵树:工作区域.暂存区域.git仓库 工作目录:平时存放项目的地方暂存区域:临时存放改动,即将提交到仓库 ...
- C语言将字符串转json
示例代码: #include <stdio.h> #include <string.h> #include <stdlib.h> char *strrpc(char ...
- OrCAD Capture CIS 16.6 在原理图页面内放置图片
OrCAD Capture CIS 16.6 菜单:Place > Picture... 在Place Picture窗口中,文件类型选择All Files (*.*),接着选择需要插入的图片, ...
- Java 写一段字符到指定的文本文档中,如果该文本文档不存在,则创建该文本文档
写一段字符到指定的文本文档中,如果该文本文档不存在,则创建该文本文档 import java.io.File; import java.io.FileNotFoundException; import ...
- 论文阅读笔记二十七:Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks(CVPR 2016)
论文源址:https://arxiv.org/abs/1506.01497 tensorflow代码:https://github.com/endernewton/tf-faster-rcnn 室友对 ...