目录
一、变量:Variables
1、基本数据类型
2、数组
二、操作符/运算符 Operators
三、表达式、语句和代码块
四、程序控制流
一、变量:Variables
Java 定义了以下几种变量:
- 实例变量/成员变量(非静态字段):Java 对象将它们各自的状态存储在“非静态字段”中,非静态字段,也就是没有使用 static 关键字声明的字段。非静态字段也被称为实例变量,因为它们的值对于每个实例(对象)都是唯一的;一辆自行车的速度与另一辆自行车的速度都是独立的。
- 类变量(静态字段):类变量是用 static 修饰符声明的字段;static 修饰符的作用是告诉编译器,不管类实例化了多少次,这个变量只存在一个副本。代码 static int numGears = 6;声明了一个静态字段。此外,也可以添加 final 关键字,以表明 numGears 的值永远不会改变。
- 局部变量:对象的状态存储在非静态字段中,而方法通常将临时状态存储在局部变量中。局部变量仅对声明它们的方法可见;该类中的其他部分无法访问该方法的局部变量。
- 参数:在 Java 的 main 方法中:public static void main(String[] args),args 变量是这个方法的参数。参数总是被归类为“变量”而不是“字段”。
1、基本数据类型
Java 支持 8 种基本数据类型:// 8-bit 为 1 字节
byte:字节类型是一个 8-bit、有符号的二进制补码整数。最小值为 -128,最大值为127(含)。在大型数组中,字节类型对于节省内存空间非常有用。
short:短整型数据类型为 16-bit、有符号的二进制补码整数。最小值为 -32,768,最大值为32,767(含)。与 byte 一样,在节省内存非常重要的情况下,可以使用 short 来节省内存。
int:int 数据类型是 32-bit、有符号的二进制补码整数。对于整数值,默认使用此类型。
long:长整型数据类型为 64-bit、有符号的二进制补码整数。当需要表示的值范围大于 int 类型时,使用此数据类型进行替代。
float:float 数据类型是一个单精度、32-bit 的浮点数。与 byte 和 short 一样,如果需要在大型浮点数数组中需要节省内存,则应该使用 float(而不是double)。注意,这种数据类型永远不应该用于精确的值,比如货币。如果要表示货币类型,应该使用 java.math.BigDecimal 替代。
double:double 数据类型是一个双精度、64-bit 的浮点数。对于小数值,默认使用此类型。同样,这种数据类型永远不应该用于精确的值,比如货币。// 计算会出现误差
boolean:布尔型数据类型只有 true 和 false 两种可能的值。这种数据类型表示一个 bit 的信息,但它的“大小”并不是精确定义的。
char:char 数据类型是一个16-bit 的 Unicode 字符。它的最小值为 '\u0000'(或0),最大值为 '\uffff'(或65,535含)。// 16-bit -> 2字节
除了上面列出的 8 种基本数据类型之外,Java 还通过 Java .lang. String 类提供了对字符串的支持。使用双引号括住一个字符串就会自动创建一个新的 String 对象;例如,String s = "this is a String ";字符串对象是不可变的,这意味着一旦创建,它们的值就不能更改。
(1)基本数据类型的默认值
声明一个字段时并不一定需要进行赋值。对于已声明但未被初始化的字段,编译器会为其设置默认值。一般来说,根据数据类型,默认值会设置为 0 或 null。
下图总结了上述数据类型的默认值:
Data 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 |
注意:编译器不会为未初始化的局部变量进行赋值。如果局部变量不能在声明的地方进行初始化,那么要确保在使用它之前对它进行赋值,访问未初始化的局部变量将导致编译不通过。
(2)Java 中的字面量标记
整数字面量标记:
整数字面量可以用以下数字系统表示:
- 十进制:以10为基数,由数字0到9组成,默认为十进制
- 十六进制:以16为进制,由数字0 ~ 9和字母A ~ F组成,前缀 0x 表示十六进制
- 二进制:基数2,其数字由数字0和1组成,前缀 0b 表示二进制
// The number 26, 十进制
int decVal = 26;
// The number 26, 十六进制
int hexVal = 0x1a;
// The number 26, 二进制
int binVal = 0b11010;
浮点数字面量标记:
浮点字面值如果以字母 F 或 f 结尾,则为 float 类型;否则它的类型就是 double,并且可以选择以字母 D 或 d 结尾。
浮点类型也可以用 E 或 e 表示(用于科学计数法)、F 或 f(32-bit 单精度字面值)和 D 或 d (64-bit 双精度字面值;这是默认值,按惯例可以省略)。// 使用 E 表示小数点的位置
double d1 = 123.4;
// same value as d1, but in scientific notation
double d2 = 1.234e2;
float f1 = 123.4f;
Character and String 字面量标记:
char 和 String 类型可以包含任何 Unicode (UTF-16) 字符。如果编辑器和文件系统允许,你可以直接在代码中使用这些字符。但如果不支持,你可以使用转义符进行转义。
Java 还支持一些针对 char 和 String 字面值的特殊转义序列:\b(退格)、\t(制表符)、\n(换行)、\f(换行)、\r(回车)、\"(双引号)、\'(单引号)和\\(反斜杠)。
还有一个特殊的 null 文字,可以用作任何引用类型的值。null 可以赋给除基本类型外的任何变量。对于 null 值,除了测试它是否存在之外,几乎没有什么其他作用。因此,在程序中经常使用 null 作为标记,表示某些对象不可用。
最后,还有一种特殊的字面量,称为类字面量,由类型名+".class"构成;例如,String.class。
在数字文字中使用下划线字符:
long creditCardNumber = 1234_5678_9012_3456L;
long socialSecurityNumber = 999_99_9999L;
float pi = 3.14_15F;
long hexBytes = 0xFF_EC_DE_5E;
2、数组
数组是一个容器对象,它包含固定数量的单一类型的值。数组的长度在创建数组时就已经指定。在创建之后,它的长度是不可变的。
数组中的每一项都称为一个元素,每个元素都通过它的数值索引来访问。
数组的操作类: java.util.Arrays
在 Java 中使用工具类 Arrays,方便了对数组的操作,如下,复制一个数组:
class ArrayCopyOfDemo {
public static void main(String[] args) {
String[] copyFrom = {
"Affogato", "Americano", "Cappuccino", "Corretto", "Cortado",
"Doppio", "Espresso", "Frappucino", "Freddo", "Lungo", "Macchiato",
"Marocchino", "Ristretto" };
String[] copyTo = java.util.Arrays.copyOfRange(copyFrom, 2, 9);
for (String coffee : copyTo) {
System.out.print(coffee + " ");
}
}
}
Arrays 类中的方法还提供了的其他一些有用的操作,详情请阅读 Arrays 类的 API。
二、操作符/运算符 Operators
// 操作符这章比较简单,只列举一些常见的操作符举例
下表中的操作符按优先级顺序列出。操作符越靠近表的顶部,它的优先级就越高。优先级较高的操作符在优先级相对较低的操作符之前进行计算。同一行上的操作符具有相同的优先级。当相同优先级的运算符出现在同一个表达式中时,必须有一个规则规定先计算哪个运算符。除赋值操作符外,所有二进制操作符都从左向右求值;赋值操作符从右向左求值。
Operators | Precedence |
---|---|
postfix 后置式 | expr++ expr-- |
unary 一元运算 | ++expr --expr +expr -expr ~ ! |
multiplicative 乘法 | * / % |
additive 加减 | + - |
shift 位移 | << >> >>> |
relational 关系 | < > <= >= instanceof |
equality | == != |
bitwise AND | & |
bitwise exclusive OR | ^ |
bitwise inclusive OR | | |
logical AND | && |
logical OR | || |
ternary 三元 | ? : |
assignment 赋值 | = += -= *= /= %= &= ^= |= <<= >>= >>>= |
一元操作符(自增或自减)
一元操作符只需要一个操作数;它们可以执行各种操作,例如,将值加1或减1,对表达式求反,或反转布尔值。
Operator | Description |
+ | Unary plus operator; indicates positive value (numbers are positive without this, however) |
- | Unary minus operator; negates an expression |
++ | 增量运算符;使一个值增加1 |
-- | 减运算符;将一个值减1 |
! | Logical complement operator; inverts the value of a boolean |
赋值操作中的自增和自减操作
自增或自减操作符可以应用于操作数之前(前缀)或操作数之后(后缀)。代码 result++ 或 ++result,当执行结束后,result 都将加1。唯一的区别是前缀版本(++result)是计算之前增加值(使用增加的值),而后缀版本(result++)是计算之后增加值(使用原始的值)。如果你只是执行简单的递增或者递减操作(单独使用),那么选择哪个版本其实并不重要。但如果在其他表达式中使用此操作符,那么不同的选择可能会产生显著差异。
下面的程序演示了前缀和后缀的一元增量运算符:
class PrePostDemo {
public static void main(String[] args){
int i = 3;
i++;
// prints 4
System.out.println(i);
++i;
// prints 5
System.out.println(i);
// prints 6
System.out.println(++i);
// prints 6
System.out.println(i++);
// prints 7
System.out.println(i);
}
}
位移操作符
一元逐位补码运算符“~”,用来反转位模式;它可以应用于任何整数类型,使每个“0”都变成“1”,每个“1”都变成“0”。例如,一个字节包含8位;将此运算符应用于 “00000000” 后,将其模式更改为“11111111”。
带符号左移操作符 “<<” 将位模式向左移动,带符号右移操作符 “>>” 将位模式向右移动。无符号右移运算符 “>>>” 将 0 移到最左边的位置。
public static void main(String[] args){
System.out.println (100 << 2); // print 400
System.out.println (100 >> 2); // print 25
System.out.println (100 >>> 2);// print 25
}
三、表达式、语句和代码块
表达式是由变量、操作符和方法调用组成的构造,这些变量、操作符和方法调用是根据语言的语法构造的。下面为表达式的例子:
int cadence = 0;
anArray[0] = 100;
System.out.println("Element 1 at index 0: " + anArray[0]);
int result = 1 + 2; // result is now 3
if (value1 == value2)
System.out.println("value1 == value2");
语句大致相当于自然语言中的句子。一条语句形成了一个完整的执行单元,通过使用分号(;)来结束一个表达式。下面是一些表达式语句的例子:
// assignment statement
aValue = 8933.234;
// increment statement
aValue++;
// method invocation statement
System.out.println("Hello World!");
// object creation statement
Bicycle myBike = new Bicycle();
代码块是一组介于花括号之间的零条或多条语句。下面的例子说明了代码块的使用:
class BlockDemo {
public static void main(String[] args) {
boolean condition = true;
if (condition) { // begin block 1
System.out.println("Condition is true.");
} // end block one
else { // begin block 2
System.out.println("Condition is false.");
} // end block 2
}
}
四、程序控制流
// Java 中的一些控制流,大部分人都比较熟悉,因为是做知识梳理,所以只会简单带过。
Java 支持的控制流有:决策流(if-then、if-then-else、switch)、循环语句(for、while、do-while)和分支语句(break、continue、return)。
循环语句中,do-while 和 while 之间的区别在于 do-while 在循环的底部而不是顶部计算其表达式。因此,do 代码块中的语句总是至少执行一次。
for 循环提供了一种紧凑的方法来迭代一系列值,它重复循环直到满足特定条件。for 循环的一般形式可以表示为:
for (initialization; // 初始化表达式 -> 循环开始的位置
termination; // 终止条件 -> false时种植循环
increment) { // 增量表达式 -> 在循环的每次迭代之后调用
statement(s)
}
for 循环的三个表达式是可选的;可以按如下方式创建一个无限循环:
// infinite loop
for ( ; ; ) {
// your code goes here
}
break 语句
break 语句有两种形式:有标记和无标记。使用一个无标记的 break 终止 for、while 或 do-while 循环,如下所示:
class BreakDemo {
public static void main(String[] args) {
int[] arrayOfInts =
{ 32, 87, 3, 589,
12, 1076, 2000,
8, 622, 127 };
int searchfor = 12;
int i;
boolean foundIt = false;
for (i = 0; i < arrayOfInts.length; i++) {
if (arrayOfInts[i] == searchfor) {
foundIt = true;
break;
}
}
if (foundIt) {
System.out.println("Found " + searchfor + " at index " + i);
} else {
System.out.println(searchfor + " not in the array");
}
}
}
无标记的 break 语句将终止最里面的 switch、for、while 或 do-while 语句,而标记的 break 语句可以终止外部的循环语句。下面的程序与前面的程序类似,但是使用嵌套的 for 循环在二维数组中搜索值。当找到值时,用一个带标签的 break 结束外部的 for 循环("search"为标记):
class BreakWithLabelDemo {
public static void main(String[] args) {
int[][] arrayOfInts = {
{ 32, 87, 3, 589 },
{ 12, 1076, 2000, 8 },
{ 622, 127, 77, 955 }
};
int searchfor = 12;
int i;
int j = 0;
boolean foundIt = false;
search: // 这是一个标记
for (i = 0; i < arrayOfInts.length; i++) {
for (j = 0; j < arrayOfInts[i].length;
j++) {
if (arrayOfInts[i][j] == searchfor) {
foundIt = true;
break search;
}
}
}
if (foundIt) {
System.out.println("Found " + searchfor + " at " + i + ", " + j);
} else {
System.out.println(searchfor + " not in the array");
}
}
}
continue 语句
continue 语句跳过 for、while 或 do-while 循环的当前迭代。不带标签的表单跳转到最内层循环体的末尾,并计算控制循环的布尔表达式。// continue 也分为带标签和不带标签两种
class ContinueDemo {
public static void main(String[] args) {
String searchMe = "peter piper picked a " + "peck of pickled peppers";
int max = searchMe.length();
int numPs = 0;
for (int i = 0; i < max; i++) {
// interested only in p's
if (searchMe.charAt(i) != 'p')
continue;
// process p's
numPs++;
}
System.out.println("Found " + numPs + " p's in the string.");
}
}
带标签的 continue 语句跳过使用给定标签标记的外部循环的当前迭代。下面的示例程序 ContinueWithLabelDemo 使用嵌套循环在另一个字符串中搜索子字符串。当中两个嵌套循环:一个用于遍历子字符串,另一个用于遍历正在搜索的字符串。下面的程序 ContinueWithLabelDemo 使用带标签形式的 continue 跳过外部循环中的迭代。
class ContinueWithLabelDemo {
public static void main(String[] args) {
String searchMe = "Look for a substring in me";
String substring = "sub";
boolean foundIt = false;
int max = searchMe.length() -
substring.length();
test:
for (int i = 0; i <= max; i++) {
int n = substring.length();
int j = i;
int k = 0;
while (n-- != 0) {
if (searchMe.charAt(j++) != substring.charAt(k++)) {
continue test;
}
}
foundIt = true;
break test;
}
System.out.println(foundIt ? "Found it" : "Didn't find it");
}
}
return 语句
return 语句表示从当前方法退出,控制流返回到调用该方法的地方。return 语句有两种形式:一种返回值,另一种不返回值。return 语句比较简单,在此不做过多赘述。