@
变量
Java语言是强类型(strongly typed)语言,强类型包含两方面的含义:①所有的变量必须先声明、后使用;②指定类型的变量只能接受类型与之匹配的值。这意味着每个变量和每个表达式都有一个在 编译时就确定的类型。类型限制了一个变量能被赋的值,限制了一个表达式可以产生的值,限制了在这 些值上可以进行的操作,并确定了这些操作的含义。
强类型语言可以在编译时进行更严格的语法检查,从而减少编程错误。
声明变量的语法非常简单,只要指定变量的类型和变量名即可:
type varName=[初始值];
常量
与变量相对应的是常量。
在 Java 中, 利用关键字 final 指示常量。
final double CM = 2.54;
关键字 final 表示这个变量只能被赋值一次。一旦被赋值之后,就不能够再更改了。习惯上,常量名使用全大写。
Java数据类型划分
Java语言支持的类型分为两类:基本数据类型和引用数据类型。
基本类型包括boolean类型和数值类型——数值类型分为整数类型和浮点类型。 整数类型包括byte、short、 int、long、char;浮点类型包括 float 和 double,char代表字符型,实际上字符型也是一种整数类型,相当于无符号整数类型。
引用类型包括类、接口和数组类型。所谓引用数据类型就是对一个对 象的引用,对象包括实例和数组两种。实际上,引用类型变量就是一个指针,只是Java语言里不再使 用指针这个说法。
Java基本数据类型
整形
通常所说的整型,实际指的是如下4种类型。
- byte: 一个byte类型整数在内存里占8位,表数范围是:-128(-2^7)~ 127(2^7-1)
- short: 一个short类型整数在内存里占16位,表数范围是:-32768(-2^15) ~ 32767(2^15 - 1)。
- int: 一个 int 类型整数在内存里占 32 位,表数范围是:-2,147,483,648(-2^31) ~ 2147483647(23I-l)o
- long: 一个long类型整数在内存里占64位,表数范围是:-9,223,372,036,854,775,808(-2^63) ~ 9,223,372,036,854,775,807(2^63 -1)。
int是最常用的整数类型,因此在通常情况下,直接给出一个整数值默认就是int类型。除此之外, 有如下两种情形必须指出。
> 如果直接将一个较小的整数值(在byte或short类型的表数范围内)赋给一个byte或short变量, 系统会自动把这个整数值当成byte或者short类型来处理。
> 如果使用一个巨大的整数值(超出了 int类型的表数范围)时,Java不会自动把这个整数值当成 long类型来处理。如果希望系统把一个整数值当成long类型来处理,应在这个整数值后增加1 或者L作为后缀。通常推荐使用L,因为英文字母1很容易跟数字1搞混。
计算机中数字存储
所有数字在计算机底层都是以二进制形式存在的,原码是直接将一个数值换算成二进制数。但计算机以补码的形式保存所有的整数。补码的计算规则:正数的补码和原码: 完全相同,负数的补码是其反码加1;反码是对原码按位取反,只是最高位(符号位)|保持不变。
字符
字符型通常用于表示单个的字符,字符型值必须使用单引号 ' ' 括起来。Java语言使用16位的 Unicode字符集作为编码方式,而Unicode被设计成支持世界上所有书面语言的字符,包括中文字符。
因此Java程序支持各种语言的字符。
字符型值有如下三种表示形式。
- 直接通过单个字符来指定字符型值,例如'A'、'9'。
- 通过转义字符表示特殊字符型值,例如' ', ' '等。
- 直接使用Unicode值来表示字符型值,格式是'uXXXX',,其中XXXX代表一个十六进制的整数。 Java语言中常用的转义字符如下。
转义字符 | 说 明 | Unicode表示方式 |
---|---|---|
退格符 | u0008 | |
换行符 | u000a | |
回车符 | u000d | |
制表符 | u0009 | |
" | 双引号 | u0022 |
' | 单引号 | u0027 |
反斜线 | u005c |
char类型的变量、值完全可以参与加、减、乘、除等数学运算,也可以比较大小,实际上都是用该字符对应的编码参与运算。
public class CharTest {
public static void main(String[] args) {
//直接指定单个字符作为字符值
char aChar = 'a';
//使用转义字符来作为字符值
char enterChar = '
';
//使用Unicode编码值来指定字符值
char ch = 'u9999';
//将输出一个'香'字符
System.out.println(ch);
//定义一个,疯'字符值
char zhong ='疯';
//直接将一个char变量当成int类型变量使用
int zhongValue = zhong;
System.out.println(zhongValue);
//直接把一个0-65535范围内的int整数赋给一个char变量
char c = 97;
System.out.println(c);
}
}
Unicode 和 char 类型
要想弄清 char 类型, 就必须了解 Unicode 编码机制。
ASCII
计算机中,数据都是以二进制的形式存在的。每一个二进制位(bit)有0和1两种状态,因此八个二进制位就可以组合出256种状态,这被称为一个字(byte)。也就是说,一个字节一共可以用来表示256种不同的状态,每一个状态对应一个符号,就是256个符号,从0000 0000到1111 1111。
上个世纪60年代,美国制定了一套字符编码,对英语字符与二进制位之间的关系,做了统一规定。这被称为 ASCII 码,一直沿用至今。
ASCII 码一共规定了128个字符的编码,比如空格SPACE是32(二进制00100000),大写的字母A是65(二进制01000001)。这128个符号(包括32个不能打印出来的控制符号),只占用了一个字节的后面7位,最前面的一位统一规定为0。
Unicode
英语用128个符号编码就够了,但是用来表示其他语言,128个符号是不够的。
所以各个地区和国家采用了不同同的编码。比如西欧语言中的ISO 8859-1 俄罗斯的 KOI-8、 中国的 GB 18030 和 BIG-5 等。
但是,这里又出现了新的问题。不同的国家有不同的字母,因此,哪怕它们都使用256个符号的编码方式,代表的字母却不一样。比如,130在法语编码中代表了é,在希伯来语编码中却代表了字母Gimel (ג),在俄语编码中又会代表另一个符号。但是不管怎样,所有这些编码方式中,0--127表示的符号是一样的,不一样的只是128--255的这一段。
至于亚洲国家的文字,使用的符号就更多了,汉字就多达10万左右。一个字节只能表示256种符号,肯定是不够的,就必须使用多个字节表达一个符号。比如,简体中文常见的编码方式是 GB2312,使用两个字节表示一个汉字,所以理论上最多可以表示 256 x 256 = 65536 个符号。
世界上存在着多种编码方式,同一个二进制数字可以被解释成不同的符号。因此,要想打开一个文本文件,就必须知道它的编码方式,否则用错误的编码方式解读,就会出现乱码。为什么电子邮件常常出现乱码?就是因为发信人和收信人使用的编码方式不一样。
设计 Unicode 编码的目的就是要解决这些问题——将世界上所有的符号纳入其中。在 20 世纪 80 年代开始启动设计工作时,设计人员认用两个字节的代码宽度对世界上各种语言的所有字符进行编码, 并留有空间留给未来的扩展。在 1991 年发布了 Unicode 1.0, 当时仅占用 65 536 个代码值中不到一半的部分。在设计 Java 时决定采用 16 位的 Unicode 字符集,这样相比较 8 位字符集的程序序设计语言有是一个很大的改进。
UTF-8
Unicode 只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。
随着互联网的普及,出现一种统一的编码方式。UTF-8 就是在互联网上使用最广的一种 Unicode 的实现方式。其他实现方式还包括 UTF-16(字符用两个字节或四个字节表示)和 UTF-32(字符用四个字节表示),不过在互联网上基本不用。
浮点
Java的浮点类型有两种:float(单精度)和double(双精度)。Java的浮点类型有固定的表数范围和字段长度,字段长度和表数范围与机器无关。Java的浮点数遵循IEEE 754标准,采用二进制数据的科学计数法来表示浮点数,对于float型数值,第1位是符号位,接下来8位表示指数,再接下来的23位表示尾数;对于 double类型数值,第1位也是符号位,接下来的11位表示指数,再接下来的52位表示尾数。
- S: 浮点数的符号位,0代表正数,1代表负数。
- Exponent: 阶码,用移码表示。
- Significand: 尾数,用原码表示,小数点放在尾数域的最前面。
Java语言的浮点数有两种表示形式。
- 十进制数形式:这种形式就是简单的浮点数,例如5.12、512.0、.512。浮点数必须包含一个小数点,否则会被当成int类型处理。
- 科学计数法形式:例如5.12e2 , 5.12E2 。
需要注意的是只有浮点类型的数值才可以使用科学计数法形式表示。例如,51200是一个int类 型的值,但512E2则是浮点类型的值。
Java语言的浮点类型默认是double类型,如果希望Java把一个浮点类型值当成float类型处理,应 该在这个浮点类型值后紧跟f或F。例如,5.12代表一个double类型的值,占64位的内存空间;5.12f 或者5.12F才表示一个float类型的值,占32位的内存空间。当然,也可以在一个浮点数后添加d或D 后缀,强制指定是double类型,但通常没必要。
布尔
boolean类型,用于表示逻辑上的“真”或“假”。在Java语言中,boolean类型的数值只能是true或false,不能用0或者非0来代表。其他基本数据类型的值也不能转换成boolean类型。
Java规范并没有强制指定boolean类型的变量所占用的内存空间。虽然boolean类型的变量或值只要1位即可保存,但由于大部分计算机在分配内存时允许分配的最小内存单元是字节(8位),因此boolean大部分时候占8位。
Java基本数据类型转换
在Java程序中,不同的基本类型的值经常需要进行相互转换。Java语言所提供的7种数值类型之 间可以相互转换,有两种类型转换方式:自动类型转换和强制类型转换。
自动类型转换
Java所有的数值型变量可以相互转换,如果系统支持把某种基本类型的值直接赋给另一种基本类型 的变量,则这种方式被称为自动类型转换。当把一个表数范围小的数值或变量直接赋给另一个表数范围 大的变量时,系统将可以进行自动类型转换;否则就需要强制转换。
表数范围小的可以向表数范围大的进行自动类型转换:
public class AutoConversion {
public static void main(String[] args) {
int a = 6;
// int类型可以自动转换为float类型
float f = a;
//下面将输出6.0
System.out.println(f);
//定义一个byte类型的整数变量
byte b = 9;
//下面代码将出错,byte类型不能自动类型转换为char类型
// char c = b;
// byte类型变量可以自动类型转换为double类型
double d = b;
//下面将输出9.0
System.out.println(d);
}
}
强制类型转换
表数范围小的可以向表数范围大的进行自动类型转换,反之则需要通过强制类型转换( cast) 实现。强制类型转换的语法格式是在圆括号中给出想要转换的目标类型,后面紧跟待转换的变量名。
public class NarrowConversion {
public static void main(String[] args) {
int iValue = 233;
//强制把一个比七类型的值转换为byte类型的值
byte bValue = (byte)iValue;
//将输出-23
System.out.println(bValue);
double dValue = 3.98;
//强制把一个double类型的值转换为int类型的值
int tol = (int)dValue;
//将输出3
System.out.println(tol);
}
}
当强制类型转换的志而又超出了目标类型的表示范围,就会出现数值丢失的情况。
参考:
【1】:《Java核心技术 卷一》
【2】:《疯狂Java讲义》
【3】:http://blog.itmyhome.com/2015/03/java-study-notes-datatype
【4】:https://www.runoob.com/java/java-basic-datatypes.html
【5】:https://blog.csdn.net/Deft_MKJing/article/details/79460485
【6】:《计算机组成原理》