相干面试题
咱们从学习 Java 开始,很快就会遇到 Java 中的数据类型 这个问题。对于数据类型,对于初学者来说,很容易记混,因为 Java 中的数据类型划分的有点多。所以在招聘高级程序员时,面试官就会常常在这一块出一些题目,对求职者进行根底语法方面的考核。常见的数据类型相干的面试题如下:
请说一下 Java 中有哪些数据类型?
Java 中有哪些根本数据类型?
根本数据类型的取值范畴是多大?
Java 的 2 个字节占多少位?
int 占几个字节?
数据类型之间怎么进行转换?
……
当然对于下面这些面试题,并不一定就这么问,很多时候面试官可能会把题干进行批改,但考查的内容其实还是这些内容。总之,万变不离其宗,Java 里的知识点就那些货色,再怎么问,也都是这些内容。
本篇文章会带大家来温习 Java 中的数据类型,这些内容个别都是以记忆为主!
一. 题目剖析
以上这些题目,其实都是围绕着 Java 中的数据类型来进行发问的,考查的重点就是求职者对数据类型的掌握情况。因为 Java 中数据类型分类较多,初学者容易记混,并且在数据类型这一块又波及到类型转换,开发时有可能会因为类型转换导致一些 bug。另外咱们在编写代码时,不同的变量也应该抉择适合的数据类型,这样有利于优化内存调配。所以面试官针对这些来发问,目标就是在考查求职者的语言根底是否扎实。
二. Java 中的数据类型
咱们在接触任何一种编程语言时,都会存在对数据类型的意识,有简单的,也有简略的。这些数据类型都须要咱们在学习初期去理解和把握,所以各位请跟着 壹哥 来看看对于数据类型的常识吧。
- 动态类型和强类型
因为 Java 语言是 动态类型的(statical typed),也就是说 Java 中的所有变量和表达式的类型,在编译时就曾经齐全确定了。所以咱们在应用变量时,必须先申明其类型,即在创立的那一刻就曾经确定好了该变量的类型。在前面的应用中,你只能将这一指定类型的数据赋值给该变量,如果强行将其余不相干类型的数据赋值给它,就会引发谬误。比方一旦申明了一个 int 类型的变量,那么之后就只能将 int 类型的数据赋值给它,否则就会引发谬误。
因为 Java 是动态类型 statical typed 的语言,这也就导致了 Java 是 强类型(Strong typed) 的语言,因为语言的强弱体现在对类型的查看严格与否上。弱类型语言对于变量类型的查看比拟宽松,容忍隐式类型转换这种事件的产生,强类型则反之。所以强类型意味着每个变量都必须具备一种类型,每个表达式也都必须具备一种类型,并且每种类型都是有严格定义的。类型限度了该变量能够持有存储哪类值,表达式最终产生什么类型的值,同时也限度了这些值能够进行的操作类型以及操作的具体形式。所有的赋值操作,无论是显式的、还是在办法调用中通过参数传递的,都要进行类型的兼容性查看。
- 数据类型概念
当初通过下面壹哥对动态类型和强类型概念的介绍后,咱们就能够很好的了解数据类型的概念了。
所谓的数据类型,在计算机语言外面,咱们能够把它了解成是针对内存地位的一种形象的表达方式。简略的来说,数据类型就是对数据的一种分类,依据每种数据各自的特点进行类别的划分,每种数据类型都与其余类型不同。举个栗子:咱们能够把不同的数据类型了解为存储在不同箱子里的不同类别的内容,有的箱子里只能装固体,有的箱子里只能装液体,有的箱子里只能装气体 …… 这些箱子会寄存在不同的中央,外面的货色也不能混装,每个箱子里的货色也都属于不同的分类。
- 数据类型分类
在 Java 外面,整体上把数据类型分成了两大类:根本类型(primitive types) 8 个 和 援用类型(reference types) 5 个,咱们来看一张残缺的分类图,如下所示:
接下来我会对根本类型和援用类型别离进行介绍。
3.1 根本类型
根本类型 是 Java 中预约义的类型,有相应的保留关键字来示意,具备明确的取值范畴和数学行为,示意了实在的数字、字符和整数。根本类型的数据都是单个值,不是简单的对象,所以根本类型并不是面向对象的,这次要是出于效率方面的思考。但同时 Java 中也为根本类型提供了对应的对象版本,即根本类型的包装类(wrapper)。咱们能够间接应用这些根本类型,也能够应用根本类型的结构数组或者其余自定义类型。
根本类型 包含布尔 (boolean) 类型、数值类型(numeric types),数值类型又分为 整型(integer types) 和 浮点型(floating-point type)。整型有 5 种:byte、short、int、long、char(char 实质上是一种非凡的 int);浮点类型有 float 和 double。所以根本数据类型分类如下:
byte、short、int、long、float(单精度)、double(双精度)、char、boolean
根本类型具体信息表:
3.2 援用类型
援用类型 (The value of reference types are references to objects) 中的援用,个别是指某个对象的内存地址,其中对象是动态创建的类实例或者动态创建的数组。另外 Java 语言自身不反对 C ++ 中的构造体(struct) 或联合体(union) 等数据类型,这种复合数据类型个别都是通过类或接口进行结构。援用数据类型分类如下:
类、接口、数组、枚举、注解
3.3 对于 null 值
另外还有一个非凡的值 null,我这里再给各位解释一下。null 是一种非凡的 type,但你不能申明一个变量为 null 类型,null type 的惟一取值就是 null。null 能够赋值给任意的援用类型或者转化成任意的援用类型。咱们在开发时,个别是把 null 当做常量字面值,这个字面值能够赋值给任意的援用类型。
- 根本类型与援用类型的区别
不论是根本数据类型还是援用类型,他们都会先在栈中调配一块内存。对于根本类型来说,这块内存区域中蕴含的是根本类型的具体数据内容;对于援用类型来说,这块内存区域中蕴含的是指向真正内容的指针,而真正的内容则被手动的调配在了堆中。
三. 根本类型的取值范畴
- 根本类型取值范畴
回顾了 Java 中的数据类型之后,咱们再来温习一下根本类型的取值范畴大小。咱们晓得,所有的根本数据类型都有固定的存储范畴和所占有的内存空间大小,且不受具体操作系统的影响,以保障 Java 程序的可移植性。每种数据类型所占的内存空间大小如下:
byte: 1 个字节,取值范畴 -128 到 127
short: 2 个字节,取值范畴 -32768 到 32767
int: 4 个字节,取值范畴 -2147483648(- 2 的 31 次方) 到 2147483647(2 的 31 次方 -1)
long: 8 个字节,取值范畴 -9223372036854775808(- 2 的 63 次方) 到 9223372036854775807(2 的 63 次方 -1)
float: 4 个字节,取值范畴 -3.40E+38 到 +3.40E+38 有效位数 7 - 8 位
double: 8 个字节,取值范畴 -1.79E+308 到 +1.79E+308 有效位数 15-16 位
char: 2 个字节,取值范畴 0-65535,共 65536 个字符
boolean: 不确定,取值范畴 true、false
根本类型取值范畴详情表:
所以从上表中,咱们就能够晓得,Java 中的 int 占了 4 个字节 32 位。
- 各根本类型大小关系
另外咱们还能够用下图展现各根本类型按取值范畴大小的比照关系:
四. 根本类型之间的转换
- 类型转换
在 Java 中,将一种类型的值赋给另一种类型是很常见的,在这个赋值过程中有可能会进行类型的转换,转换分为主动转换和强制转换。主动类型转换 (隐式转换) 无需进行任何操作,而强制类型转换则须要显式转换,即须要应用强制转换操作符(type)。
留神:
boolean 类型与其余所有的 7 种类型都不能进行类型转换,而其余 7 种根本类型彼此之间都能够进行转换,但可能会呈现精度损失或者其余的一些变动。
- 主动转换
2.1 主动转换机会
那么什么时候会进行主动转换呢?
个别当一个较 ” 小 ” 的数据与一个较 ” 大 ” 的数据一起运算时,零碎会主动将 ” 小 ” 数据转换成 ” 大 ” 数据,再进行运算,这时就产生了主动转换。
首先咱们将 7 种类型按从小到大的顺序排列一下:
byte < (short=char) < int < long < float < double
这里咱们所说的 ” 大 ” 与 ” 小 ”,并不是指占用的字节有多少,而是指示意值的范畴大小。
在下面的 7 种类型之间,如果数据类型是从小转换到大,能够进行主动转换,主动转换时会产生扩宽 (widening conversion);而从大到小,必须进行强制转换;short 和 char 两种类型之间也必须强制转换。这是因为较大的类型(如 int) 要保留较小的类型(如 byte),内存总是足够的,不须要强制转换。咱们间接将整型字面值(常量) 赋值到 byte、short、char、long 时,其实也是主动进行了类型转换。比方上面的源码:
//“小”转“大”,主动转换
byte b = 100;
int i;
i = b;
System.out.println(“i=” + i);
//“大”转“小”,强制转换
int i;
float f = 20000f;
i = (int) f;
System.out.println(“i=” + i);
//short 与 char 之间须要强制类型转换
short s = 100;
char c = 90;
s=(short)c;
System.out.println(“s=”+s);
2.2 主动转换时的精度损失
除了以下几种状况可能会导致精度损失以外,其余的转换都不会呈现精度损失。
int–> float
long–> float
long–> double
float –>double without strictfp
除了可能的精度损失外,主动转换时不会呈现任何运行时异样。
- 强制转换
3.1 强制转换语法
如果要把 ” 大 ” 的转成 ” 小 ” 的,或者在 short 与 char 之间进行转换,就必须进行强制转换。这也被称作放大转换(narrowing conversion),这是因为必须显式地使数值变得更小 以适应指标类型。严格地说,将 byte 转为 char 不属于放大转换 narrowing conversion,因为从 byte 到 char 的过程其实是 byte–>int–>char,也就是既有扩宽操作 widening,也有放大操作 narrowing。强制转换时须要采纳转换操作符(指标根本类型),格局如下:(target-type) value
// 强制转换案例
int x=300;
byte y;
y = (byte)x;
3.2 强制转换的问题
另外强制转换除了可能的精度损失外,还可能使模 (overall magnitude) 发生变化。即如果整数的值超出了 byte 所能示意的范畴,后果将对 byte 类型的范畴取余数。例如 a =257 超出了 byte 的 [-128,127] 的范畴,所以会将 257 除以 byte 的最大范畴(256),而后失去余数 b =1。须要留神的是,当 a =200 时,此时除去 256 获得的余数应该为 -56,而不是 200。
// 强制转换时模产生了变动
int a = 257;
byte b;
b = (byte) a;
System.out.println(“b=” + b);//b=1
//a=200,余数 =-56
int a = 200;
byte b;
b = (byte) a;
System.out.println(“b=” + b);//-56
将浮点类型赋给整数类型的时候,会产生截尾(truncation),也就是会把小数的局部去掉,只留下整数局部。此时如果整数超出指标类型范畴,一样会对指标类型的范畴取余数。
// 浮点赋值给整形, 会截尾
float f=100.58f;
int i;
i=(int)f;
System.out.println(“i=”+i);//100
强制转换时可能会导致溢出或精度的失落。
3.3 表达式中数据类型的主动晋升
咱们表达式中可能会有 +、-、*、/ 等各种操作符,在执行这些表达式时,则可能会产生数据类型的主动晋升,有以下规定:
所有的 byte、short、char 型的值将被晋升为 int 型;
如果有一个操作数是 long 型,计算结果是 long 型;
如果有一个操作数是 float 型,计算结果是 float 型;
如果有一个操作数是 double 型,计算结果是 double 型。
// 表达式中的类型主动晋升
byte b;
b = 10;
// 因为此时 b 曾经进行了类型晋升, 所以如果这里不进行强制类型转换则会报错
//b=b*2;
// 此时必须进行强制类型转换
b=(byte)(b*3);
System.out.println(“b=”+b);//b=30
// 类型晋升为 long
int i=400;
long l=500;
// 这样会报错
//int x=i+l;
// 这样没问题
long x=i+l;
System.out.println(“x=”+x);//x=900
五. 论断
至此,壹哥 就给大家梳理出了“Java 中数据类型”相干面试题的答案,咱们再看看前文中提到的面试题!
而后我再梳理一下这些问题的答复要点:
先简略回顾 Java 中的数据类型;
而后具体阐明 Java 中的 8 种根本类型,每种类型的作用、取值范畴;
接着说一下各类型之间的转换问题;
具体说一下主动类型转换和强制类型转换。
这些面试题的重点答案,我已在内容中用红色表明了,这些内容须要了解的货色并不多,次要是以记忆为主,各位好好记一下吧!