[转载] Java内存管理-你真的理解Java中的数据类型吗(十)

参考链接: Java中的字符串类String 1

做一个积极的人 

 编码、改bug、提升自己 

 我有一个乐园,面向编程,春暖花开! 

 

 

 推荐阅读 

 第一季 

 0、Java的线程安全、单例模式、JVM内存结构等知识梳理 1、Java内存管理-程序运行过程(一) 2、Java内存管理-初始JVM和JVM启动流程(二) 3、Java内存管理-JVM内存模型以及JDK7和JDK8内存模型对比总结(三) 4、Java内存管理-掌握虚拟机类加载机制(四) 5、Java内存管理-掌握虚拟机类加载器(五) 6、Java内存管理-类加载器的核心源码和设计模式(六) 7、Java内存管理-掌握自定义类加载器的实现(七) 第一季总结:由浅入深JAVA内存管理 Core Story 

 

 

 第二季 

 8、Java内存管理-愚人节new一个对象送给你(八) 【福利】JVM系列学习资源无套路赠送 9、Java内存管理-”一文掌握虚拟机创建对象的秘密”(九) 10、Java内存管理-你真的理解Java中的数据类型吗(十) 11、Java内存管理-Stackoverflow问答-Java是传值还是传引用?(十一) 12、Java内存管理-探索Java中字符串String(十二) 

 

 

 实战 

 一文学会Java死锁和CPU 100% 问题的排查技巧 

 

分享一位老师的人工智能教程。零基础!通俗易懂!风趣幽默! 大家可以看看是否对自己有帮助,点击这里查看【人工智能教程】。接下来进入正文。 

勿在流沙筑高台,出来混迟早要还的。 

作为Java程序员,Java 的数据类型这个是一定要知道的! 但是不管是那种数据类型最终存储都要到内存中,本文由浅入深对数据类型进行介绍和讲解,相信读完本文你一定会有收获的,会对Java数据类型有更深的了解和认识! 

本文地图 

 

一、什么是位、字节、字符、字符集 

位(bit):计算机内部存储数据的最小单位,音译为比特,每个二进制数字0或者1就是1个位! 

字节(Byte):计算机**存储容量(数据处理)**的基本单位,音译拜特,8个位构成一个字节;即:1 byte (字节)= 8 bit(位)。 

一个字节能够存放的数字范围用二进制表示为00000000011111111,也就是8个bit(比特),8个比特转换为无符号的10进制数字范围是0255,转换为有符号数据一般为-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码是最熟知字符编码,编码范围为0255,属于单字节编码。ASCII码编码范围太小了,Java为了能够处理多字节语言编码(比如中文、日文、韩文等)编码范围0x0000000x10FFFF,采用国际组织制定的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 是我随便写的一个值,真实的内存地址并不是这个,这个值只是为了我画图方便! 

在多强调一点,在引用类型中,对于类来说,要创建对象其实包括两步,第一是声明对象,第二是创建对象! 

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;Java 在编译的时候会直接将代码封装成Integer i1=Integer.valueOf(40);,从而使用常量池中的对象。Integer i1 = new Integer(40);这种情况下会创建新的对象。 

Integer i1 = 40;

Integer i2 = new Integer(40);

System.out.println(i1==i2);//输出false

 

最后在贴出阿里巴巴Java手册中对包装类使用的建议: 

 

四、本文总结 

本文整体内容相对基础,但是在java开发中还是非常重要,注重细节和基础,让写出的每一行代码都是最优的!朝着这个方向努力! 下一篇整理一下值传递和引用传递! 敬请期待! 

备注: 由于本人能力有限,文中若有错误之处,欢迎指正。 

五、参考资料 

1、可能是把Java内存区域讲的最清楚的一篇文章 

2、Java语言中一个字符占几个字节? 

 

谢谢你的阅读,如果您觉得这篇博文对你有帮助,请点赞或者喜欢,让更多的人看到!祝你每天开心愉快! 

 

 

 Java编程技术乐园:一个分享编程知识的公众号。跟着老司机一起学习干货技术知识,每天进步一点点,让小的积累,带来大的改变!

 

 

 

 扫描关注,后台回复【资源】,获取珍藏干货! 99.9%的伙伴都很喜欢

 

 

 

 

 © 

 每天都在变得更好的阿飞云

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/540228.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux系统安全加固脚本

闲来无事&#xff0c;整理一个系统安全加固脚本&#xff0c;每个公司的要求不一样&#xff0c;所以仅供参考&#xff1a; #!/bin/sh echo "00 */1 * * * /usr/sbin/ntpdate 192.168.1.1 >>/var/log/ntpdate.log" > mycrontab crontab mycrontab rm -rf my…

[转载] 整理下java中stringBuilder和stringBuffer两个类的区别

参考链接&#xff1a; Java中的StringBuffer类 StringBuilder和StringBuffer这两个类在动态拼接字符串时常用&#xff0c;肯定比String的效率和开销小&#xff0c;这是因为String的对象不会回收哦。 其实我一直用StringBuilder这个类&#xff0c;因为可以简写为sb的变量在程序…

11.13 模10计数器设计

.新建一个工程 Family&#xff1a;FLEX10K Available device&#xff1a;EPF10K20TC144-3 2.设置lpm_counter宏单元参数并连接引脚 连接引脚的时候要注意的是&#xff0c;向量线的连接。 3.时序仿真 检查无误后进行下一步 4.载入7448并进行引脚连接 5.分配管脚 再次编译&#x…

[转载] java对象在内存中的结构

参考链接&#xff1a; 了解Java中的类和对象 今天看到一个不错的PPT&#xff1a;Build Memory-efficient Java Applications&#xff0c;开篇便提出了一个问题&#xff0c;在Hotspot JVM中&#xff0c;32位机器下&#xff0c;Integer对象的大小是int的几倍&#xff1f; 我们…

使用valueOf前必须进行校验

每个枚举都是java.lang.Enum的子类,都可以访问Enum类提供的方法,比如hashCode(),name(),valueOf()等..... 其中valueOf()方法会把一个String类型的名称转变为枚举项,也就是枚举项中查找出字面值与该参数相等的枚举项,虽然这个方法很简单,但是JDK却做了一个对于开发人员来说并不…

[转载] 【Java】Java基础知识及其扩展笔记(8千字)

参考链接&#xff1a; Java中的StringBuilder类及其示例 Java基础知识及其扩展笔记 零 l 写在前面一 l JVM1、【1.1.2.1】java程序运行的一般流程2、【1.1.2.1】JVM一般运行流程3、【1.1.2.1】JIT&#xff08;just in time 即时编译编译器&#xff09;4、堆与栈 二 l Java …

多IDC GSLB的部署

之前已经介绍过GSLB的实现原理&#xff0c;这里再向大家讲述一下GSLB经常遇到的部署方式&#xff0c;多IDC的部署。很多大型的企业或业务容灾要求非常高的客户都会部署有多个异地的数据中心&#xff0c;以保证其业务的“全天候”不间断的正常运行&#xff0c;而要整合多个IDC的…

[转载] Controller报错:java.lang.NoSuchMethodException: java.util.List.<init>()

参考链接&#xff1a; Java8中的java.util.StringJoiner 报错详情&#xff1a; java.lang.NoSuchMethodException: java.util.List.<init>() 以及 No primary or default constructor found for interface java.util.List 示例&#xff1a; /** * 此接口会产生以…

[转载] 算法竞赛中的JAVA使用笔记

参考链接&#xff1a; Java中StringTokenizer类的示例| 1(构造函数) 算法竞赛中的JAVA使用笔记 算法竞赛中的JAVA使用笔记 输入与输出 基本输入输入挂输出控制台输入输出重定向到文件 大整数与高精度 大整数BigInteger高精度BigDecimal高精度开方 字符串与进制转换 字符串基本…

信息系统开发平台OpenExpressApp:【OpenTest】 之 语法及其使用介绍

在OpenTest 之 运行环境准备中介绍了运行自动化测试需要做的一些准备工作&#xff0c;本篇将继续给大家介绍OpenTest的脚本语法以及使用方法&#xff0c;通过学习后读者应该能够开始动手编写UI自动化测试脚本了。 关键字驱动测试 在学习语法之前&#xff0c;需要了解一下关键字…

[转载] java常量池-字符串常量池、class常量池和运行时常量池

参考链接&#xff1a; 如何在Java中初始化和比较字符串 原文链接&#xff1a;http://tangxman.github.io/2015/07/27/the-difference-of-java-string-pool/ 在java的内存分配中&#xff0c;经常听到很多关于常量池的描述&#xff0c;我开始看的时候也是看的很模糊&#xff0c…

Oracle 10g 高级安装图文教程(二)

第八步&#xff1a;为了简便起见&#xff08;工作中肯定不安全&#xff09;&#xff0c;选择“所有的帐户都是用同一个口令”&#xff0c;并输入口令&#xff0c;点击“下一步”&#xff1a;本文转自 victoryan 51CTO博客&#xff0c;原文链接:http://blog.51cto.com/victoryan…

[转载] StringBuffer和StringBuilder类

参考链接&#xff1a; Java中的String vs StringBuilder vs StringBuffer 下述文章资料来源于&#xff1a; W3CSCHOOL离线版的Java教程 Java JDK 6.0开发手册 Java开发从入门到精通(陈小玉版) StringBuffer和String选择的异同 StringBuffer在进行字符串处理时&#xff0c;不…

sharepoint 2007功能增强解决方案,资料收集

一、关于QuickFlow&#xff0c;sharepoint可视化工作流增强包 http://www.cnblogs.com/jianyi0115/tag/QuickFlow/default.html?page1 http://quickflow.codeplex.com/ 二、关于SharePoint Permission Extension&#xff0c;视图、列表字段权限功能增强 http://sppex.codeplex…

[转载] 面试题:说说Java中接口、类、成员变量、成员方法、构造方法有哪些访问修饰符和他们的作用范围

参考链接&#xff1a; Java中的访问修饰符 * 问题&#xff1a;说说Java中接口、类、成员变量、成员方法、构造方法有哪些访问修饰符和他们的作用范围 * 答&#xff1a;接口的访问修饰符只有public 1个 * 类的访问修饰符有public和默认(就是不写的)2个 * 成员方法的访问修…

使用IHttpHandler做权限控制[ASP.NET | IHttpHandler | AjaxPro | UserHostName]

正文 Web.Config配置如下: <add verb"POST,GET"path"/page/*.aspx,/page/*/*.aspx,/page/*/*/*.aspx,/page/*/*/*/*.aspx,/page/*/*/*/*/*.aspx"type"WebLibrary.PowerManage.HttpHanderPowerControls"/> 整个IHttpHandler实现代码如下: /…

[转载] Java 中字符串转整型和整型转字符串

参考链接&#xff1a; Java中的字符串到整数– parseInt() Java 中字符串转整型和整型转字符串 1.字符串转整型Java代码&#xff0c;字符串为纯数字的情况下&#xff0c;调用Integer的静态方法parseInt或者valueOfJava代码&#xff0c;如果单个字符或字符串&#xff0c;需要切…

Gram matrix 格拉姆矩阵

2019独角兽企业重金招聘Python工程师标准>>> Gram matrix 度量各个维度自己的特性以及各个维度之间的关系。 来自&#xff1a;https://www.zhihu.com/question/49805962?fromprofile_question_card 由感知机&#xff08;对偶感知机中需要计算样本点两两之间的内积和…

[转载] 用Java语言实现对十六进制字符串异或运算

参考链接&#xff1a; 交换两个字符串&#xff0c;而无需在Java中使用第三个用户定义的变量 前言&#xff1a;好久没有写博客&#xff0c;最近一年感觉真是好忙&#xff0c;各种做不完的工作。相信很多上班族都会有这种感觉。最近对NFC进行写卡操作&#xff0c;需要计算一个校…

MySQL日常应用操作记录

1.知道一个字段名&#xff0c;怎样查到它在数据库里的哪张表里&#xff1f; USE Information_schema;SELECT TABLE_NAME FROM COLUMNS WHERE COLUMN_NAME字段名称; MySQL中查看库表字段信息都在information_schemal中&#xff0c;获取数据字典等信息都要通过这个视图。 如&…