前面的话
此文的编写参考了较多经典文献:《Java Rules》、《Java Language Specification 7》、《Java Virtual Machine Specification 7》、《Core Java》、《Java JDK8学习笔记》等,所以比较权威,不过鄙人才疏学浅,出错在所难免,望指出。
块(block)
块是指放在大括号中的一连串语句、局部类声明和局部变量声明语句。
块确定了变量的作用域。一个块可以嵌套在另一个块中。
一个块可以嵌套在另一个块中。下面是main方法中嵌套另一个语句块的示例:
public static void main(String[] args)
{
int n;
...
{
int k;
...
} // k is noly defined up to here
}
但是,不能在嵌套的两个块中声明相同的变量。例如,下面代码无法通过编译:
public static void main(String[] args)
{
int n;
...
{
int k;
...
int n; // Error--can't redefine n in inner block
}
}
在C++中,可以在嵌套的块中定义一个变量。在内层定义的变量会覆盖外层定义的变量。这样,有可能会导致程序设计错误,在Java中不被允许。
块是从上到下,从左到右执行每个局部变量声明和其它语句的。如果所有块语句正常结束,那么块就正常结束。如果出于任何原因,这些块的任何语句突然结束,那么块就出于相同原因突然结束。
突然结束总有一个相关的原因,为下列原因之一:
- 无给定标签的break
- 有给定标签的break
- 无给定标签的continue
- 有给定标签的continue
- 无值的return
- 有值的return
- 具有指定值的throw,包括JVM抛出的异常
局部类声明(Local Class Declarations)
局部类是一个嵌套类,该嵌套类不是任何一个类的成员,并且具有一个名称。JLS原文:a local class is a nested class that is not a member of any class and that has a name
所有的局部类都是内部类。
所有局部类的声明语句直接包含于块中,并且可以和其它语句一起出现在块中。JLS原文:every local class declaration statement is immediately contained by a block. Local class declaration statements may be intermixed freely with other kinds of statement in the block
如果局部类声明包含下面访问修饰符的任何之一,那么它就是一个编译时错误:public 、 protected 、 private 或 static 。
下面是上面给出的规则的几个方面的示例:
class Global {
class Cyclic {}
void foo() {
new Cyclic(); // create a Global.Cyclic
class Cyclic extends Cyclic {}; //circular definition
{
class Local {};
{
class Local {}; //compile-time error
}
class Local {}; //complile-time error
class AnotherLocal {
void bar() {
class Local {} // ok
}
}
}
class Local {} // ok, not in scope of prior Local
}
}
方法foo的第一条语句创建了成员类Global.Cyclic的一个实例,而不是创建局部类Cyclic的一个实例,因为局部类声明仍不在此作用域中。
局部类作用域包含它自己的声明(而不是它的体)意味着局部类Cyclic的定义确实是循环的,因为它扩展了自身,而不是扩展了Global.Cyclic。因此,局部类Cyclic的声明将在编译时被拒绝。
由于局部类名称不能在相同的方法(或构造函数或初始化等其它可能的情况)重新进行声明,所以Local 的第二和第三个声明导致了编译时错误。但Local可以在另一个(更加深层嵌套的)类(比如AnotherLocal)的上下文中进行重新声明。
Local的第4个和最后一个声明是合法的,因此它在Local任何之前声明的作用域之外发生。
*Tips:看了这么久我猜你也没怎么看懂,其实说的就是局部内部类*
局部变量声明和作用域
这一部分在Java语言规范中讲的晦涩难懂,如果想了解这一部分可以看如下博客:
语句(Statement)
空语句(Empty Statement)
一条空语句将什么都不做,语法为一个分号;
空语句的执行始终正常完成。
标签语句(Labeled Statement)
Java没有C/C++的goto语句,goto作为保留字存在。
标签语句时和break或continue语句一起使用的,这些语句出现在标签语句中的任何地方。
如果语句是通过Identifier加标签的,并且包含的Statement由于具有相同Identifier的break突然结束,那么标签语句就突然结束,在Statement的所有其它突然结束的情形中,标签语句出于相同原因突然结束。
break with label:1
2
3
4
5
6
7
8
9
10
11
12
13
14class Test {
public static void main(String[] args) {
back:
{
for (int i = 0; i < 10; i++) {
if (i == 9) {
System.out.println("break");
break back;
}
}
System.out.println("test");
}
}
}
程序执行结果会显示break
continue with label:1
2
3
4
5
6
7
8
9
10
11
12class Test {
public static void main(String[] args) {
back1:
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
if (j == 9) {
continue back1;
}
}
}
}
}
continue配套标签的使用时,标签只能在循环内部,否则会出现编译错误。
表达式语句(Expression Statement)
某些类别的表达式通过在它们后面加个分号可以用作语句:
ExpressionStatement:
StatementExpression;
StatementExpression:
- Assignment
- PreIncrementExpression
- PreDecrementExpression
- PostIncrementExpression
- PostDecrementExpression
- MethodInvocation
- ClassInstanceCreationExpression
表达式语句时通过求表达式的值执行的:如果表达式具有一个值,那么该值就被丢弃。当且仅当表达式的求值正常结束时,表达式语句的执行才正常结束。
if语句(If Then [else] Statement)
语法格式:
if (condition) statement
与绝大多数程序设计语言一样,Java希望在某个条件为真时执行多条语句。在这种情况下,应该使用块语句(block statement)。
使用块(有时称为复合语句)可以在Java程序结构中原本只能放置一条简单语句的地方放置多条语句。Java中,常见的语句格式如下:
if (condition) {
statement1
}
else {
statement2
}
//condition必须具有boolean或Boolean类型,否则会出现编译错误
Tips
Apple 曾提交一个IOS上的安全更新:http://support.apple.com/kb/HT6147。原因是在某个函式中有两个连续的缩排:
...
if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
goto fail;
goto fail; // always do
if ((err = SSLHashSHA1.final(&hashCtx, &signedParams)) != 0)
goto fail;
...
因为缩排在同一层,阅读代码时大概没有注意到,又没有定义块,结果会出现goto fail无论如何都会被执行的错误。
所以在写if…else语句时,可读性是应当被重视的一件事。在编写条件控制语句时,首先要做的是理清思路再写代码。
assert语句(Assert Statement)
由于JLS讲的太不亲民了,所以推荐别人写的优秀的博客
switch语句(Switch Statement)
在Java7以前,switch可用于比较整数、字符、Enum,Java7以后增加了字符串的比较。语法如下:
switch (变量或布尔表达式)
{
case 整数、字符、枚举或字符串
...
break;
...
default:
...
}
while语句(While Statement)
while (变量或布尔表达式){
...
}
do语句(Do Statement)
do {
...
} while (变量或布尔表达式)
for语句(For Statement)
基本for循环(BasicForStatement):
for (ForInit; Expression; ForUpdate) Statement
增强for循环(EnhancedForStatement):
for (VariableModifiers Type Identifier : Expression) Statement
