java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的 Java 程序设计语言和 Java 平台(即 JavaEE(j2ee), JavaME(j2me), JavaSE(j2se))的总称。
Java 数据类型(type)可以分为两大类:基本类型(primitive types)和引用类型(reference types)。下面是动力节点给大家整理 java 基本数据类型相关知识,感兴趣的朋友一起学习吧
1. 数据类型:
在 Java 源代码中,每个变量都必须声明一种类型(type)。Java 数据类型(type)可以分为两大类:基本类型(primitive types)和引用类型(reference types)。primitive types 包括 boolean 类型以及数值类型(numeric types)。numeric types 又分为整型(integer types)和浮点型(floating-point type)。整型有 5 种:byte short int long char(char 本质上是一种特殊的 int)。浮点类型有 float 和 double。关系整理一下如下图:
2. 基本类型:
Java 为基本类型提供语言级别的支持,即已经在 Java 中预定义,用相应的保留关键字表示。基本类型是单个值,而不是复杂的对象,基本类型不是面向对象的,主要出去效率方面的考虑,但是同时也提供基本类型的对象版本,即基本类型的包装器(wrapper)。可以直接使用这些基本类型,也可以使用基本类型构造数组或者其他自定义类型。基本类型具有明确的取值范围和数学行为。
2.1 整型
整型有 byte short int long char,分别用 8、16、32、64、16bits 表示。有些地方可能不会把 char 列入整型范畴,但本质上 char 类型是 int 的一个子集。整型的宽度不应该被看成整数所占用的内存空间大小,而应当理解成定义为整型的变量或者表达式的行为。JVM 可以自由使用它们希望的、任何大小的内存空间,只要类型的行为符合规范。byte short int long 都是有符号的,用 2 的补码(two's-complement)表示。而 char 用 16 位表示,它是无符号的,表示的是 UTF-16 编码集。
2.1.1 byte
byte 由 1 个字节 8 位表示,是最小的整数类型。主要用于节省内存空间关键。当操作来自网络、文件或者其他 IO 的数据流时,byte 类型特别有用。取值范围为:[-128, 127]. byte 的默认值为 (byte)0, 如果我们试图将取值范围外的值赋给 byte 类型变量,则会出现编译错误,例如 byte b = 128;这个语句是无法通过编译的。一个有趣的问题,如果我们有个方法: public void test(byte b)。试图这么调用这个方法是错误的: test(0); 编译器会报错,类型不兼容!!!我们记得 byte b =0;这是完全没有问题的,为什么在这里就出错啦?
这里涉及到一个叫字面值(literal)的问题,字面值就是表面上的值,例如整型字面值在源代码中就是诸如 5 , 0, -200 这样的。如果整型子面子后面加上 L 或者 l,则这个字面值就是 long 类型,比如:1000L 代表一个 long 类型的值。如果不加 L 或者 l,则为 int 类型。基本类型当中的 byte short int long 都可以通过不加 L 的整型字面值(我们就称作 int 字面值吧)来创建,例如 byte b = 100; short s = 5;对于 long 类型,如果大小超出 int 所能表示的范围(32 bits),则必须使用 L 结尾来表示。整型字面值可以有不同的表示方式:16 进制【0X or 0x】、10 进制【nothing】、八进制【0】2 进制【0B or 0b】等,二进制字面值是 JDK 7 以后才有的功能。在赋值操作中,int 字面值可以赋给 byte short int long,Java 语言会自动处理好这个过程。如果方法调用时不一样,调用 test(0)的时候,它能匹配的方法是 test(int),当然不能匹配 test(byte)方法,至于为什么 Java 没有像支持赋值操作那样支持方法调用,不得而知。注意区别包装器与原始类型的自动转换(anto-boxing,auto-unboxing)。byte d = 'A';也是合法的,字符字面值可以自动转换成 16 位的整数。
对 byte 类型进行数学运算时,会自动提升为 int 类型,如果表达式中有 double 或者 float 等类型,也是自动提升。所以下面的代码是错误的:
- byte s2 = 'a';
- byte sum = s1 + s2;//should cast by (byte)</span></span></span>
2.1.2 short
用 16 为表示,取值范围为:[- 2^15, 2^15 - 1]。short 可能是最不常用的类型了。可以通过整型字面值或者字符字面值赋值,前提是不超出范围(16 bit)。short 类型参与运算的时候,一样被提升为 int 或者更高的类型。(顺序为 byte short int long float double).
2.1.3 int
32 bits, [- 2^31, 2^31 - 1]. 有符号的二进制补码表示的整数。常用语控制循环,注意 byte 和 short 在运算中会被提升为 int 类型或更高。Java 8 以后,可以使用 int 类型表示无符号 32 位整数 [0, 2^31 - 1]。
2.1.4 long
64 bits, [- 2^63, 2^63 - 1, 默认值为 0L]. 当需要计算非常大的数时,如果 int 不足以容纳大小,可以使用 long 类型。如果 long 也不够,可以使用 BigInteger 类。
2.1.5 char
16 bits, [0, 65535], [0, 2^16 -1], 从'\u0000'到'\uffff'。无符号,默认值为'\u0000'。Java 使用 Unicode 字符集表示字符,Unicode 是完全国际化的字符集,可以表示全部人类语言中的字符。Unicode 需要 16 位宽,所以 Java 中的 char 类型也使用 16 bit 表示。 赋值可能是这样的:
- char ch1 = 88;
- char ch2 = 'A';
ASCII 字符集占用了 Unicode 的前 127 个值。之所以把 char 归入整型,是因为 Java 为 char 提供算术运算支持,例如可以 ch2++; 之后 ch2 就变成 Y。当 char 进行加减乘除运算的时候,也被转换成 int 类型,必须显式转化回来。
2.2 浮点类型
包含单精度的 float 和双精度的 double,分别用 32、64bits 表示,遵循 IEEE 754 规范。
2.2.1 float
使用 32 bit 表示,对应单精度浮点数,运行速度相比 double 更快,占内存更小,但是当数值非常大或者非常小的时候会变得不精确。精度要求不高的时候可以使用 float 类型,声明赋值示例:
- f1 = 10L;
- f1 = 10.0f;
- //f1 = 10.0;默认为double</span></span></span>
可以将 byte、short、int、long、char 赋给 float 类型,java 自动完成转换。
2.2.2 double
64 为表示,将浮点子面子赋给某个变量时,如果不显示在字面值后面加 f 或者 F,则默认为 double 类型。java.lang.Math 中的函数都采用 double 类型。
如果 double 和 float 都无法达到想要的精度,可以使用 BigDecimal 类。
2.3 boolean 类型
boolean 类型只有两个值 true 和 false,默认为 false。boolean 与是否为 0 没有任何关系,但是可以根据想要的逻辑进行转换。许多地方都需要用到 boolean 类型。
3. 字面值
在 Java 源代码中,字面值用于表示固定的值(fixed value)。数值型的字面值是最常见的,字符串字面值可以算是一种,当然也可以把特殊的 null 当做字面值。字面值大体上可以分为整型字面值、浮点字面值、字符和字符串字面值、特殊字面值。
3.1. 整型字面值
从形式上看是整数的字面值归类为整型字面值。例如: 10, 100000L, 'B'、0XFF 这些都可以称为字面值。整型字面值可以用十进制、16、8、2 进制来表示。十进制很简单,2、8、16 进制的表示分别在最前面加上 0B(0b)、0、0X(0x)即可,当然基数不能超出进制的范围,比如 09 是不合法的,八进制的基数只能到 7。一般情况下,字面值创建的是 int 类型,但是 int 字面值可以赋值给 byte short char long int,只要字面值在目标范围以内,Java 会自动完成转换,如果试图将超出范围的字面值赋给某一类型(比如把 128 赋给 byte 类型),编译通不过。而如果想创建一个 int 类型无法表示的 long 类型,则需要在字面值最后面加上 L 或者 l。通常建议使用容易区分的 L。所以整型字面值包括 int 字面值和 long 字面值两种。
3.2. 浮点字面值
浮点字面值简单的理解可以理解为小数。分为 float 字面值和 double 字面值,如果在小数后面加上 F 或者 f,则表示这是个 float 字面值,如 11.8F。如果小数后面不加 F(f),如 10.4。或者小数后面加上 D(d),则表示这是个 double 字面值。另外,浮点字面值支持科学技术法表示。下面是一些例子:
- double d2 = 11.4;
- double d3 = 1.23E3;
- double d4 = 10D;
- double d5 = 0.4D;
- float f1 = 10;
- float f2 = 11.1F;
- float f3 = 1.23e-4F;
- float f4 = 1.23E0F; < /span>/
3.3 字符及字符串字面值
Java 中字符字面值用单引号括起来,如 '@''1' 。所有的 UTF-16 字符集都包含在字符字面值中。不能直接输入的字符,可以使用转义字符,如'\n'为换行字符。也可以使用八进制或者十六进制表示字符,八进制使用反斜杠加 3 位数字表示,例如'\141'表示字母 a。十六进制使用 \ u 加上 4 为十六进制的数表示,如'\u0061'表示字符 a。也就是说,通过使用转义字符,可以表示键盘上的有的或者没有的所有字符。常见的转义字符序列有:
\ddd(八进制) 、 \uxxxx(十六进制 Unicode 字符)、\'(单引号)、\"(双引号)、\\ (反斜杠)\r(回车符) \n(换行符) \f(换页符) \t(制表符) \b(回格符)
字符串字面值则使用双引号,字符串字面值中同样可以包含字符字面值中的转义字符序列。字符串必须位于同一行或者使用 + 运算符,因为 java 没有续行转义序列。
3.4 特殊字面值
null 是一种特殊的类型(type),可以将它赋给任何引用类型变量,表示这个变量不引用任何东西。如果一个引用类型变量为 null,表示这个变量不可用。
还有一种特殊的 class literal,用 type name 加上. class 表示, 例如 String.class。首先,String 是类 Class(java.lang.Class) 的一个实例(对象),而 "This is a string" 是类 String 的一个对象。然后,class literal 用于表示类 Class 的一个对象,比如 String.class 用于表示类 Class 的对象 String。简单地说,类子面子(class literal)就是诸如 String.class 、Integer.class 这样的字面值,它所表示的就是累 String、类 Integer。如果输出 Integer.class,你会得到 class java.lang.Integer。List.class 的输出为 interface java.util.List。总之,class literal 用于表示类型本身!
3.5 在数值型字面值中使用下划线。
JDK7 开始,可以在数值型字面值(包括整型字面值和浮点字面值)插入一个或者多个下划线。但是下划线只能用于分隔数字,不能分隔字符与字符,也不能分隔字符与数字。例如 int x = 123_456_789. 在编译的时候,下划线会自动去掉。可以连续使用下划线,比如 float f = 1.22___33__44. 二进制或者十六进制的字面值也可以使用下划线,记住一点,下划线只能用于数字与数字之间,初次以外都是非法的。例如 1._23 是非法的,_123、11000_L 都是非法的。
4. 基本类型之间的转换
我们看到,将一种类型的值赋给另一种类型是很常见的。在 Java 中,boolean 类型与所有其他 7 种类型都不能进行转换,这一点很明确。对于其他 7 中数值类型,它们之间都可以进行转换,但是可能会存在精度损失或者其他一些变化。转换分为自动转换和强制转换。对于自动转换(隐式),无需任何操作,而强制类型转换需要显式转换,即使用转换操作符(type)。首先将 7 种类型按下面顺序排列一下:
- byte < (short = char) < int < long < float < double
如果从小转换到大,可以自动完成,而从大到小,必须强制转换。short 和 char 两种相同类型也必须强制转换。
4.1 自动转换
自动转换时发生扩宽(widening conversion)。因为较大的类型(如 int)要保存较小的类型(如 byte),内存总是足够的,不需要强制转换。如果将字面值保存到 byte、short、char、long 的时候,也会自动进行类型转换。注意区别,此时从 int(没有带 L 的整型字面值为 int)到 byte/short/char 也是自动完成的,虽然它们都比 int 小。在自动类型转化中,除了以下几种情况可能会导致精度损失以外,其他的转换都不能出现精度损失。
- 》int--> float
- 》long--> float
- 》long--> double
- 》float -->double without strictfp
除了可能的精度损失外,自动转换不会出现任何运行时(run-time)异常。
4.2 强制类型转换
如果要把大的转成小的,或者在 short 与 char 之间进行转换,就必须强制转换,也被称作缩小转换(narrowing conversion), 因为必须显式地使数值更小以适应目标类型。强制转换采用转换操作符()。严格地说,将 byte 转为 char 不属于 narrowing conversion),因为从 byte 到 char 的过程其实是 byte-->int-->char,所以 widening 和 narrowing 都有。强制转换除了可能的精度损失外,还可能使模(overall magnitude)发生变化。强制转换格式如下:
- byte b;
- b = (byte)a;//1</span>
如果整数的值超出了 byte 所能表示的范围,结果将对 byte 类型的范围取余数。例如 a=256 超出了 byte 的 [-128,127] 的范围,所以将 257 除以 byte 的范围(256)取余数得到 b=1;需要注意的是,当 a=200 时,此时除了 256 取余数应该为 - 56,而不是 200.
将浮点类型赋给整数类型的时候,会发生截尾(truncation)。也就是把小数的部分去掉,只留下整数部分。此时如果整数超出目标类型范围,一样将对目标类型的范围取余数。
7 种基本类型转换总结如下图:
4.3 赋值及表达式中的类型转换:
4.3.1 字面值赋值
在使用字面值对整数赋值的过程中,可以将 int literal 赋值给 byte short char int,只要不超出范围。这个过程中的类型转换时自动完成的,但是如果你试图将 long literal 赋给 byte,即使没有超出范围,也必须进行强制类型转换。例如 byte b = 10L;是错的,要进行强制转换。
4.3.2 表达式中的自动类型提升
除了赋值以外,表达式计算过程中也可能发生一些类型转换。在表达式中,类型提升规则如下:
》所有 byte/short/char 都被提升为 int。
》如果有一个操作数为 long,整个表达式提升为 long。float 和 double 情况也一样。
来源: http://www.phperz.com/article/17/1218/357770.html