「每天一个知识点」Java中的数据类型

Java语言本身是一个强类型的语言,这就意味着在声明一个变量时必须规定其数据类型。在Java中有8种基本数据类型,其中包括4个整数类型,2个浮点类型,1个字符型,1个布尔型

整数类型用来表示没有小数部分的数值,它允许是负数。在Java中一共有4个整数类型,主要区别在于每个类型的存储大小以及取值范围,具体如下:

一般情况下,int类型是最常用的,但是在处理数字较大的数据时可能就需要用到长整型long。long类型的数据后边需要加上大写的L或者小写l,表示当前的数据类型为长整型,例如:

浮点类型用来表示带有小数部分的数值,在Java中一共有2个整数类型,主要的区别在于其存储的大小以及取值的范围,具体如下:

float类型的精度是小数点后6~7位,double类型的精度是小数点后15位,是float类型精度的2倍。double类型是最常用的浮点类型。如果要声明一个float类型的变量,需要在数值后边添加一个大写的F或者小写的f,如果没有F则会被默认位double类型。例如:

char是一种用于表示Unicode编码的字符单元的字符类型,它通过一对单引号表示。例如’A‘就是65所对应的字符常量。这里涉及到了Unicode编码,可以参考下方的文章读懂编码的问题,这里就不做过多的介绍。

布尔(boolean)类型有两个值,true和false,通常用于逻辑判断。整数类型和布尔类型之间不可以相互转换。

程序在运行期间,经常会将一种数据类型转换成另一种数据类型,此时就会涉及到数据类型转换的问题。数据类型在转换时分为”自动转换“和”强制转换“两种。

自动转换是指存储小的空间类型向存储大的空间类型转换,在转化时不需要额外的操作,直接进行转换。具体转换类型如下:

图中实线箭头表示转换的时候数据的精度不会有丢失,虚线的箭头表示在转换的过程中精度可能会造成丢失的情况。整数类型无论占用的空间有多大都是可以转换成浮点类型的。

强制转换是指存储大的空间类型向存储小的空间类型转换,例如double类型转换成int类型。此时就需要用到强制类型转换。但是这种类型转换可能会丢失一些信息。例如:

此时就是将double类型的变量n强制转换成了int类型的变量m,在转换时需要在变量前加上要转换的类型

1、在Java当有8种基本数据类型,分别是byte、short、int、long、float、double、boolean、char。其具体分类如下:

2、数据类型之间是可以进行转换的,当小存储空间向大存储空间转换时为自动类型转换,当大存储空间向小存储空间转换时为强制类型转换

Java编程高手速成:Java的基本数据类型特点以及高效记忆

Java 基本数据类型概览

Java作为一种广泛使用的高级编程语言,其强大的功能之一就体现在它对基本数据类型的精细划分上。Java的基本数据类型是构成程序的基础元素,它们包括整型、浮点型、字符型和布尔型,每种类型都有其独特的用途和特性。

整型数据类型在Java中分为四种:byte、short、int和long,它们主要用于表示整数。byte类型占用1个字节,取值范围为-128(-2^7)到127(2^7-1);short类型占用2个字节,取值范围从-32,768((-2^15))到32,767((-2^15-1));int类型是最常用整数类型,占用4个字节,取值范围为-2^31到2^31-1;而long类型则占用8个字节,取值范围更广,为-2^63到2^63-1。

浮点型数据类型包括float和double两种,它们用于表示带有小数的数字。float类型称为单精度浮点数,占用4个字节,有效数字大约7位;而double类型称为双精度浮点数,占用8个字节,有效数字大约15位。浮点数的精度对于科学计算或需要高精度数值运算的场景尤为重要。

字符型数据类型char在Java中用于表示单个字符,它占用2个字节,能够表示Unicode字符集中的所有字符,从而支持国际化编程。char类型的取值范围为0到65,535,对应于UTF-16编码单元。

布尔型数据类型boolean是Java中专用于逻辑判断的类型,只有两个取值:true(真)和false(假)。它在内存中占用的空间非常小,通常为1个比特,但由于计算机体系结构的原因,实际占用空间可能稍大。

这些基本数据类型构成了Java程序的基础,了解它们的属性和使用场景对于编写高效、正确的Java代码至关重要。在实际开发中,根据不同的需求选择合适的数据类型,可以有效地优化程序的性能和内存使用。例如,对于大量数据的运算,选择适当的整型可以减少内存消耗;对于需要精确表示的小数,应优先考虑使用double类型以确保计算精度。

各基本数据类型的字节数与取值范围

在Java编程中,基本数据类型是构建程序的基础元素。每种数据类型都对应不同的字节数和取值范围,了解这些特性有助于程序员更高效地使用内存资源并避免潜在的错误。首先,整型数据分为几种:byte、short、int、和long,其中byte占用1字节,其取值范围从-2^7至2^7-1;short占用2字节,取值范围为-2^15至2^15-1;int是最常用的整型,占用4字节,取值范围为-2^31至2^31-1;而long占用8字节,取值范围最大,从-2^63至2^63-1。浮点型数据包括float和double,float占4字节,主要用于科学计算和需要小数部分的场合,其有效数字大约为6到7位;double则占用8字节,精度更高,适用于需要更精确数值计算的情况。

字符型数据char在Java中用于表示单个字符,每个char占用2字节,可以存储UTF-16编码的字符。这种设计使得Java能够支持多语言环境中的国际化需求。布尔型数据boolean只有两种状态,true和false,它在计算机中通常只占用1位,但在Java中由于最小的数据单位是字节,因此实际占用空间为1字节。这些基本数据类型的设计和实现体现了Java对效率与功能的综合考量。例如,通过为不同大小的数值提供不同长度的数据类型,Java允许开发者根据实际需求选择最合适的数据类型,从而优化内存使用和提高程序性能。同时,字符型的设计也显示了Java对全球语言支持的重视。

基本数据类型在内存中的存储原理

在Java中,基本数据类型的存储方式是直接在内存中以固定的大小分配空间。每种基本数据类型都有其特定的字节数和默认值,这些特性直接影响其在程序中的声明、初始化以及使用。

当声明一个变量时,系统会根据该变量的数据类型在堆或栈内存中为其分配相应大小的内存空间。例如,整型(int)占用4个字节,而布尔型(boolean)只占用1个字节。这种固定大小的特性使得Java在编译时就能确定每个变量所需的内存量,从而提高了程序的运行效率。

初始化变量时,Java为基本数据类型的变量赋予了默认值。例如,数值型(byte、short、int、long)的默认值是0,浮点型(float、double)的默认值是0.0,字符型(char)的默认值是’\\u0000’(即null字符),布尔型(boolean)的默认值是false。这些默认值确保了未显式初始化的变量有一个确定的起始状态,减少了程序运行时可能出现的错误。

在内存中,基本数据类型通常被存储在连续的字节中。例如,一个int类型的变量可能会被存储在四个连续的字节内。这种连续性不仅有助于数据的快速访问,也简化了数据的处理过程。

此外,Java的基本数据类型在内存中的布局是平台无关的,这意味着无论在哪个操作系统或硬件上运行,相同的Java代码都将以同样的方式处理其基本数据类型。这是Java“一次编写,到处运行”理念的一个体现。

了解Java中基本数据类型的存储原理对于编写高效且可靠的程序至关重要。开发者应熟悉各数据类型的字节数和默认值,以便更好地管理内存使用并预防潜在的错误,如数值溢出或类型转换错误。通过掌握这些基础知识,可以更有效地利用Java语言的特性,优化程序性能并提高代码质量。

如何高效记忆 Java 基本数据类型

如何高效记忆 Java 基本数据类型对于初学者来说至关重要,因为这是编程基础中的核心部分。以下提供几个实用的技巧和方法,帮助用户快速掌握相关知识。

将数据类型与其取值范围和内存占用进行联想记忆。例如,整型(int)通常占用 4 个字节,对应 32 位,取值范围是 -2^31 至 2^31-1。可以想象一个四格的停车场,每一个格子代表一个字节,总共有四个格子,即 32 位。通过这种方式,把抽象的概念具象化,便于记忆。此外,了解这些基本数据类型的默认值也有助于加深理解。例如,整型的默认值是 0,布尔型的默认值是 false,字符型的默认值是 ‘\\u0000’,而浮点型(float)的默认值是 0.0f。

利用对比和分类的方法进行记忆也是一种有效的策略。可以将 Java 的基本数据类型按用途和特性分成几类:数值型(如 byte、short、int、long)、浮点型(如 float、double)、字符型(char)和布尔型(boolean)。每类内部的数据类型在字节数和取值范围上都有特定的关系和规律。例如,数值型从 byte 到 long,它们的字节数依次增加一倍,取值范围也随之扩大。通过这种对比和分类,可以更系统地掌握不同数据类型之间的关系和差异。

实践是最好的老师。编写代码来测试和验证你对各种基本数据类型的理解和使用。例如,编写小程序来打印不同数据类型变量的默认值、最大值和最小值等。通过不断的练习和应用,你会发现自己对基本数据类型的掌握越来越熟练,最终能够自如地在实际编程中使用它们。

基本数据类型的应用场景

在Java编程中,基本数据类型的选择和应用至关重要,它们直接影响程序的性能和内存使用效率。整型数据类型是最常用的,如用于表示整数,适用于计数、索引等场景;占用较少的空间,适合存储小范围的整数;而则用于需要更大数值范围的情况,例如处理大文件的偏移量或时间戳。浮点型数据类型和用于表示带有小数的数字,其中提供更精确的小数点表示,适用于金融计算等对精度要求较高的场合。字符型用于存储单个字符,通常用于处理字符串或文本相关的操作。布尔型只有两个值:和,用于逻辑判断,控制程序的流程。

在实际编程中,选择合适的数据类型可以优化内存利用并提高程序效率。例如,如果知道某个数值不会超出一定范围,应优先考虑使用较小的数据类型以节省空间。同时,对于涉及大量计算的应用,选择合适的数据类型还能避免溢出问题,确保程序的正确性和稳定性。此外,理解不同数据类型之间的转换规则也是编写高效代码的关键,特别是在进行数学运算或数据处理时。总之,掌握Java基本数据类型的应用场景,可以帮助开发者更好地设计程序结构,提升编码质量。

常见问题解答

在Java编程中,基本数据类型的使用是极其常见的,但在实际开发中,开发者可能会遇到一些关于这些数据类型的问题。其中,类型转换和溢出问题是最为频繁遇到的。

类型转换问题通常出现在整型与浮点型的转换中。例如,当我们将一个较大的整数值赋给一个浮点变量时,由于浮点数的存储方式不同,可能会导致精度的丢失。同样,将一个浮点数强制转换为整型时,小数部分将会被截断,这在某些情况下可能导致意外的结果。因此,在进行类型转换时,开发者需要特别小心,尤其是在涉及到金融计算等对精度要求极高的场景。

溢出问题是另一个常见的问题。在Java中,每种基本数据类型都有一个固定的取值范围,当赋值超过这个范围时,就会发生溢出。例如,类型的取值范围是-2^31至2^31-1,如果尝试将一个超出这个范围的值赋给一个变量,结果将是不确定的,并且可能导致程序运行错误。为了避免溢出问题,开发者需要在编写代码时就考虑到数据可能的最大值,并合理选择数据类型。例如,对于可能非常大的数值,可以使用或类型来避免溢出。

除了上述两个常见问题外,还有一个值得注意的点是基本数据类型的默认值。在Java中,每个基本数据类型都有一个默认值,例如的默认值是0,的默认值是,的默认值是0.0f。了解这些默认值对于编写健壮的代码非常重要,因为它们可以在对象未显式初始化时提供合理的默认行为。

总结来说,虽然Java的基本数据类型看似简单,但在实际应用中却有许多需要注意的地方。理解类型转换的规则、避免溢出以及利用好默认值,都是提高代码质量和减少潜在错误的关键步骤。掌握这些知识,可以帮助开发者更加熟练地使用Java进行高效编程。

Java数据类型最全讲解

本篇我们对java的基本数据类型进行学习,同样也是面试喜欢考的基础内容,所以我们给它好好地过一遍。

首先我们得知道,java有两大数据类型:

基本数据类型(又叫内置数据类型)

引用数据类型

基本数据类型比较简单,就是int、long这样的,引用数据类型类似c++的指针,它指向一个对象,我们用的所有的对象或数组都属于引用数据类型,它的默认值都是null。

本篇文章关注的是基本数据类型,但是同时也会说明这些基本类型对应的包装类,这个包装类就是引用类型。

java有8种基本数据类型,这个需要记住

4个整数类型:byte、short、int、long

2个浮点数类型:float、double

1个字符类型:char

1个布尔类型:boolean

看到这几个熟悉的名字,大家应该完全明白什么是基本数据类型了,简单来说,其实就是我们常用的小写的数据类型

下图是它们所占的位数和字节数,其中boolean没有明确的定义,但是一般是只占一位。

E是科学计数法,E后面的数字代表E前面的数字要乘以10的多少次方,例如3.14E-3就是乘以10的负三次方:

3.14 x 0.001 =0.00314

然后这些最大值最小值,可以通过它们的包装类里的MAX_VALUEMIN_VALUE两个常量查看,例如:

关于什么是包装类,第三小节会详细说明,这里先剧透一下,就是Integer、Double之类的和基本数据类型对应的大写的类。

char类型较为特殊,它在java中是Unicode编码,且占2个字节16位,无符号,所以它的范围0-65535。可以理解成可以存65536个不同的符号,但是计算机是不能直接存符号的。所以它本质上其实是用整数存储,但是使用了Unicode码代表字符,每个字符都有一个专属固定的Unicode码,所以每个数字都对应一个符号。

而另一种赋值方式是通过十六位的Unicode编码,这种比较特殊,用起来可能比较少,格式就是\’\\u1234\’这样。\’\\u\’代表这是个Unicode字符,里面四位数字其实是16进制的Unicode码。char的包装类中的MAX_VALUEMIN_VALUE两个常量也是以这种方式存储的字符。

例如:对char赋值\’\\u7801\’或整数30721,结果都等于字符:码。如果你将16进制的7801计算为10进制,就会发现结果就是30721。

所以总共可以用三种形式给它赋值

①单引号包住的单个字符

②0-65535中的整数(Unicode值的十进制)

③单引号包住的字符编码(Unicode值的十六进制)

当然结果和范围是一样的,它最终只能代表一个字符,所以我们一般使用的时候用第一种方式赋值就行了。只是以后看到有人赋值整数结果却是字符时,不要大惊小怪就好。

例如:

输出的结果是一样的,都是:A

所以以后不要下意识的觉得char字符\’6\’转换为整数也是6哦,最终其实是看Unicode值的,结果应该是整数:54

这8种基本类型都有一个对应的包装类,也就是java中的另一种数据类型:引用数据类型,有自己的属性和方法,默认值为null。

我们通常使用基本数据时,也是使用它们的包装类更多。因为这些基本数据类型仅仅只能声明和存放一个值,甚至都不能为null,也没有我们常用的一些类型转换equals()方法。基本数据类型只能做做运算,而包装类就比较完善了,适合在业务中使用。

基本数据类型对应的包装类分别是:Byte、Short、Integer、Long、Float、Double、Character、Boolean。也就是除了char对应的是Character,int对应Integer,其他的都只是首字母变成大写而已。

注:这里注意一下String,它既不是基本类型也不是谁的包装类,不要误以为它是字符类型的基本类型之类的了,虽然它的重要性并不比基本类型低。

字符类的基本类型仅有char而已。

自动拆装箱大家应该有听过,它是针对基本类型和它们的包装类的,让它们可以自动进行转换。

装箱:将基本类型用它们对应的应用类型包装起来

拆箱:将包装类型转换为基本数据类型

可能这样说还不是很理解,实际上我们一直在使用这个功能,例如在java se5之前,如果要初始化一个Integer对象,是需要这样的:

看起来又正常又别扭,因为每个新对象都是通过new初始化出来的,但好像我们使用的时候从来没有这么麻烦过,一般我们是:

这就是自动装箱,理论上来说,10是基本类型的数据,只能直接赋给int类型。现在我们将它赋给了int的包装类Integer,其实就是java自动对基本数据10进行了装箱,装到了包装类中。简单的说就是替你创建了一个Integer对象,值存为10。

自动拆箱则是相反,java自动将Integer变量拆箱为具体的整数值,这样就可以做到将包装类变量直接赋给int基本数据类型。

自动拆箱:

在大部分包装类和基本类型混用的地方,都会自动进行拆装箱,下面第6小节会详细说明自动进行拆装箱的场景。

通过编译再对class字节码文件的反编译,我们可以知晓答案

首先写一段这样的测试代码:

打开cmd输入javac Test.java进行编译,得到Test.class

然后通过jd-gui工具反编译Test.class,得到如下代码:

可以看到,自动拆装箱的核心是在包装类变量上使用了两个方法,装箱时是Integer.valueOf(),通过看源码可以得知本质上是调用了new Integer初始化。拆箱时是intValue(),也是直接返回了int的值。

看来所谓高大上的自动拆装箱,其实也只是偷偷地调用了包装类的两个方法,只是我们没发现而已。另外,其他基本类型的拆装箱也是一样的,例如char的两个方法也分别是valueOf()和charValue(),大家可以自己测试一下。

总结:装箱过程是通过调用包装器的valueOf方法实现的,而拆箱过程是通过调用包装器的 xxxValue方法实现的。

除了我们最常见的赋值,还有一些其他场景会进行自动拆装箱,以下都可以通过反编译查看原理

①将基本数据类型放入集合类

例如

这里使用了自动装箱:li.add(Integer.valueOf(i));

②比较大小

结果是true,其实这里用了自动拆箱:System.out.println(a.intValue()==1);

③运算

这里使用了自动拆箱,拆成基本类型才可以进行运算:System.out.println(i.intValue()+2);

④三目运算符

这种情况比较少接触,我也是通过网上搜集资料才知道有这种情况的

这里使用了自动拆箱:int k = flag ? i.intValue() : j,当第二、第三位操作数分别是基本类型和对象时,其中的对象会自动拆箱。所以一不小心可能就会触发空指针异常,要注意一下这点。

这几个场景最需要注意的是运算这一块,以后碰到包装类的运算时,要记住它们是先拆箱为基本数据类型,再运算。

在java中,除了boolean,其他基本类型是可以自动转换的。转换的形式从低到高,也就是两个不同的基本类型在一起运算时,会按照如下的顺序,将低的转换成高的类型。

byte,short,char——》int——》long——》float——》double

byte,short和char有些特殊,就算不涉及更高的类型,它们在运算比较时也是直接自动转换为int进行处理的。举个例子也就是,如果short、int、和float类型相加,那么统一都会转换成3个float类型,然后再进行运算。

基本类型与String进行运算的话,会自动转换成String类型 ,但是这里要注意如下特殊情况:

这里从左到右,由于1+2是两个整数,所以会先计算得到3,然后3+\”3\”,则是转换成String,同理\”33\”+4,也就变成了字符串334。

Java的基本类型的包装类,大部分都实现了常量池技术: Byte,Short,Integer,Long,Character,Boolean,也就是通过了一定范围的缓存,避免重复新建对象。

Byte,Short,Integer,Long默认创建了[-128,127]范围的数据

Character默认创建了数值在[0,127]范围的数据

Boolean默认则是直接返回True 或false

这些都可以通过源码的valueOf()方法查看到,也就是当你在任何地方通过valueOf()创建基本数据时(自动装箱),它们都是从同一个常量池里先判断是否有这个值,如果有,就直接返回常量池中的对象,如果没有,才new一个新对象给你。

因此,如果你是通过自动装箱或valueOf获取的包装类对象,当数据的值在缓存范围内时,无论你获取多少次相同的数据,本质上都是指向同一个对象,所以内存地址之类的自然也都是相等的。

至于浮点数是没有缓存的,因为在某个范围里的整数是有限的,但浮点数却是无限的。即便范围是0到1,其中也有无数个浮点数,也很难定位到哪些浮点数比较常用,所以浮点数是没有常量池缓存的。

参考资料:

1.什么是Java中的自动拆装箱:

https://blog.csdn.net/wufaliang003/article/details/82347077

2.深入剖析Java中的装箱和拆箱:

https://www.cnblogs.com/dolphin0520/p/3780005.html

3.java不同基本类型之间的运算:

https://blog.csdn.net/shenzixincaiji/article/details/82735390

本文作者及来源:Renderbus瑞云渲染农场https://www.renderbus.com

点赞 0
收藏 0

文章为作者独立观点不代本网立场,未经允许不得转载。