基础数据类型

前面说到字段,Java编程语言也使用变量这个术语,字段更多是用在OOP中的上下文。这篇将介绍变量和字段之间的联系,加上变量的命名规则和约定俗成的命名规范。,基础数据类型(基本类型,字符串和数组),默认值和字面量。

基本类型

Java编程语言是静态类型的,意思就是所有的变量必须在使用之前就声明好。这包含两个方面:变量的类型和名称。如你所见:

int gear = 1;

这样就告诉你的程序,我要一个叫gear的字段,保存一个数值类型,并且初始化值为1。一个变量的数据类型决定了它能保存什么样的值,加上它能执行什么样的操作。除了 int 之外,Java还支持七种不同的基本数据类型。基本数据类型是语言内置的预定义的数据类型。它们的名称都是保留字,不能用做变量名。基本值不与其他基本值共享状态。Java一共有8种基本数据类型:

  • byte: byte 数据类型是一个8位有符号二进制补码整数。它的最小值是 -128(-2^7),最大值是 127(2^7-1)。当节约内存变得很重要的时候,字节数据类型对于节省大型数据的内存空间很又用。它们也可以用来替代 int 类型,其限制性有助于代码更清晰。
  • short: short 数据类型是一个16位有符号二进制补码整数。它的最小值是-32,768(-2^15),最大值是32,767(2^15-1)。如同 byte,你也可以用它来节省内存空间。
  • int: 默认情况下,int 是一个32位有符号二进制补码整数。最小值是-2^31,最大值是2^31-1。
  • long: long 数据类型是一个64位有符号二进制补码整数。它的最小值是-2^63,最大值是2^63-1。
  • float: float 数据类型是一个单精度32位 IEEE 754 浮点数。它的范围不在这里详述,等到后面讲到浮点数时再说。和 byteshort 一样,如果你需要在一个大型数组中节省内存空间,使用 float 替代 double 来表示一个小数。这个数据类型绝对不要用来表示精确的值,比如货币。对于这种情况,使用类 java.math.BigDecimal 替代,后面会讲到这个类。
  • double: double 数据类型是一个双精度64位 IEEE 754 浮点数。这里也不讨论它的范围,等到后面讲到浮点数时再说。正如上面提到的,double 不要用来表示精确的值,比如货币。
  • boolean: boolean 数据类型只有两个取值:truefalse。使用这个数据类型来表示条件的 true/false 状态。虽然 boolean 只表示1位的信息,但它的“大小”并没有明确的规定。在某些虚拟机中,boolean 可能是用一个字节来表示,而在其他虚拟机中可能是用一个整数来表示。
  • char: char 数据类型是一个单一的16位 Unicode 字符。它的最小值是\u0000(即0),最大值是 \uffff(即65,535)。

注意到,在Java 8 及之后的版本,你可以使用 int 类型来表示一个无符号32位整数,它的最小值是0,最大值是2^32-1。使用 Integer 类来表示一个无符号整数。该类的静态方法像 Integer.compareUnsigned() 支持无符号整数的算术运算。

Java 8 及以后的版本也可以使用 long 来表示一个无符号64位long整数,它的最小值是0,最大值是2^64-1。如果你需要表示一个范围超过int的数,就这个这个类型。Long 类提供了 Long.compareUnsigned()Long.divideUnsigned() 等方法来支持无符号长整数的算术运算。

除了上面这8种基本数据类型,Java通过 java.lang.String 类来支持字符串。使用双引号包围起来的字符会自动地创建一个 String 对象,像这样子:

String s =  "this is a string";

String 对象都是不可变的,这意味着一旦被创建,它们的值无法被更改。严格的说String 类不是基本数据类型,但考虑到Java对其提供的特殊支持,你可能也会把它视为基本数据类型。后面讲String类的时候会更详细地介绍它。

使用默认值初始化变量

在声明字段时,并非总是能有一个值,你可能不知道当前的值是什么。编译器会将声明但未初始化的字段设置为一个默认值。一般而言,该默认值为 0 或者 null,取决于数据类型。如果总是依赖于编译器给默认值,通常来说不是一个好的编程习惯。下面的表格总结了以上8种基本数据类型的默认值:

Date Type Default Value(for fields)
byte 0
short 0
int 0
long 0L
float 0.0f
double 0.0d
char \u0000
String(or any object) null
boolean false

局部变量有一点点不同。编译器从不分配一个默认值给一个未初始化的局部变量。如果你在声明时不初始化你的局部变量,确保你在使用它之前给它赋值。防卫一个未被处死绘画的局部变量会返回一个编译时错误。

使用字面量初始化变量

你可能会注意到上面的代码中没有使用new关键字初始化基本类型的变量。基本类型是一种特殊的数据类型被内置在编程语言中。它们不是一个从类创建的对象。字面量一代码层面上的固定值,字面量不需要经过计算就可以直接在代码中使用。如下所示,可以将字面量赋值给一个基本类型的变量:

boolean result = true;
char capitalC = 'C';
byte b = 100;
short s = 10000;
int i = 100000;

整型字面量

如果一个整型字面量以lL结尾,它会被当作一个long类型,否则它会被当作一个int类型。推荐使用大写的L来表示long类型,以避免和数字1混淆。

整数类型byte,short,intlong的值都可以由int字面量创建。超过int表示范围的long类型可以用long字面量创建。整型字面量可以被表达为以下几种数制:

  • Decimal:十进制,其数字由0到9组成。这是你日常使用的数制。
  • Hexadecimal: 十六进制,其数字由0到9和A到F组成。
  • Binary: 二进制,其数字由0和1组成。从Java 7开始,Java支持二进制字面量。

对于通常的编程任务,十进制很可能是你最常用的数制。然后,当你需要使用另一种数制的时候,虾米那的例子展示了正确的语法。前缀0x表明这是十六进制数,前缀0b表明是二进制数:

// The number 26, in decimal
int decimalValue = 26;

// The number 26, in hexadecimal
int hexadecimalValue = 0x1A;

// The number 26, in binary
int binaryValue = 0b11010;

浮点数字面量

F或者f结尾的浮点数字面量会被当作float类型,否则它会被当作double类型,可选地在结尾用D或者d来表示double类型。浮点类型(float 和 double)也可使用 E 或 e(表示科学记数法)、F 或 f(表示 32 位浮点数字面量)以及 D 或 d(表示 64 位双精度数字面量;此为默认形式,按惯例可省略)来表示。

double d1 = 123.4;
// same value as d1, but in scientific notation
double d2 = 1.234e2;
float f1 = 123.4f;

字符和字符串字面量

char 和 String 类型的字面量可包含任意 Unicode(UTF-16)字符。若您的编辑器和文件系统支持,可直接在代码中使用此类字符。若不支持,可使用 Unicode 转义序列,例如 \u0108(带楔形符号的大写 C)或 “S\u00ED Se\u00F1or”(西班牙语中的 Sí Señor)。字符常量始终使用’单引号’,字符串常量始终使用”双引号”。Unicode转义序列不仅限于字符或字符串常量,在程序其他位置(如字段名称)也可使用。

Java 编程语言还为字符和字符串字面量支持若干特殊转义序列:\b(退格)、\t(制表符)、\n(换行符)、\f(分页符)、\r(回车符)、\“(双引号)、\‘(单引号)以及 \\\(反斜杠)。

还存在一种特殊的空值字面量,可作为任何引用类型的值使用。空值字面量可赋值给除基本类型变量外的任何变量。除了检测其存在性外,空值几乎无法执行其他操作。因此,在程序中常将空值用作标记符,表示某些对象不可用。

最后,还存在一种特殊的字面量称为类字面量,其形式是在类型名称后附加.class;例如String.class。这指代的是代表类型本身的对象,其类型为Class

在数字字面量中使用下划线字符

在 Java SE 7 及更高版本中,数字字面量中的任意数字之间可以出现任意数量的下划线字符 (_)。此功能可让您在数字字面量中分隔数字组,从而提高代码的可读性。
例如,如果你的代码包含多位数字,可以使用下划线字符将数字分隔为三位一组,类似于使用逗号或空格等标点符号作为分隔符的方式。以下示例展示了在数字字面量中使用下划线的其他方式:

long creditCardNumber = 1234_5678_9012_3456L;
long socialSecurityNumber = 999_99_9999L;
float pi = 3.14_15F;
long hexBytes = 0xFF_EC_DE_5E;
long hexWords = 0xCAFE_BABE;
long maxLong = 0x7fff_ffff_ffff_ffffL;
byte nybbles = 0b0010_0101;
long bytes = 0b11010010_01101001_10010100_10010010;

下划线只能放置在数字之间,以下位置不能使用下划线:

  • 在数字的开头或结尾处
  • 在浮点数字面量中紧邻小数点的位置
  • 在F或L后缀之前
  • 在预期出现用字符串表示的数字序列的位置

以下示例展示了数字字面量中下划线的有效与无效位置:

// Invalid: cannot put underscores
// adjacent to a decimal point
float pi1 = 3_.1415F;
// Invalid: cannot put underscores
// adjacent to a decimal point 
float pi2 = 3._1415F;
// Invalid: cannot put underscores
// prior to an L suffix
long socialSecurityNumber1 = 999_99_9999_L;

// OK (decimal literal)
int x1 = 5_2;
// Invalid: cannot put underscores
// At the end of a literal
int x1 = 52_;
//OK (decimal literal)
int x3 = 5________2;

// Invalid: cannot put underscores
// in the 0x radix prefix
int x4 = 0_x52;
// Invalid: cannot put underscores
// at the beginning of a number
int x5 = 0x_52;
// OK (hexadecimal literal)
int x6 = 0x5_2;
// Invalid: cannot put underscores
// at the end of a number
int x7 = 0x52_;