Java常用关键字

权限修饰符

Java中,可以使用访问控制符来保护对类、变量、方法和构造方法的访问。Java 支持 4 种不同的访问权限。

  • default (即默认,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。
  • private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰外部类
  • public : 对所有类可见。使用对象:类、接口、变量、方法
  • protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰外部

我们可以通过以下表来说明访问权限:

修饰符 当前类 同一包内 子孙类(同一包) 子孙类(不同包) 其他包
public Y Y Y Y Y
protected Y Y Y Y/N N
default Y Y Y N N
private Y N N N N

protected 需要从以下两个点来分析说明:

  • 子类与基类在同一包中:被声明为 protected 的变量、方法和构造器能被同一个包中的任何其他类访问;
  • 子类与基类不在同一包中:那么在子类中,子类实例可以访问其从基类继承而来的 protected 方法,而不能访问基类实例的protected方法。

接口及接口的成员变量和成员方法不能声明为 protected。

static关键字

静态变量

运行时,Java 虚拟机只为静态变量分配一次内存,在加载类的过程中完成静态变量的内存分配。
在类的内部,可以在任何方法内直接访问静态变量。
在其他类中,可以通过类名访问该类中的静态变量。
静态变量在类中的作用如下:
静态变量可以被类的所有实例共享,因此静态变量可以作为实例之间的共享数据,增加实例之间的交互性。
如果类的所有实例都包含一个相同的常量属性,则可以把这个属性定义为静态常量类型,从而节省内存空间。

静态方法

静态方法不需要通过它所属的类的任何实例就可以被调用,因此在静态方法中不能使用 this 关键字,也不能直接访问所属类的实例变量和实例方法,但是可以直接访问所属类的静态变量和静态方法。另外,和 this 关键字一样,super 关键字也与类的特定实例相关,所以在静态方法中也不能使用 super 关键字。

静态类

全局唯一,任何一次的修改都是全局性的影响
只加载一次,优先于非静态
使用方式上不依赖于实例对象。
生命周期属于类级别,从Jvm加载开始到Jvm卸载结束。

静态代码块

静态代码块指 Java 类中的 static{ } 代码块,主要用于初始化类,为类的静态变量赋初始值,提升程序性能。
静态代码块的特点如下:

  1. 静态代码块类似于一个方法,但它不可以存在于任何方法体中。
  2. 静态代码块可以置于类中的任何地方,类中可以有多个静态初始化块。
  3. Java 虚拟机在加载类时执行静态代码块,所以很多时候会将一些只需要进行一次的初始化操作都放在 static 代码块中进行。
  4. 如果类中包含多个静态代码块,则 Java 虚拟机将按它们在类中出现的顺序依次执行它们,每个静态代码块只会被执行一次。
  5. 静态代码块与静态方法一样,不能直接访问类的实例变量和实例方法,而需要通过类的实例对象来访问。

final关键字

final 修饰变量

final 修饰的变量即成为常量,只能赋值一次,但是 final 所修饰局部变量和成员变量有所不同。
final 修饰的局部变量必须使用之前被赋值一次才能使用。
final 修饰的成员变量在声明时没有赋值的叫“空白 final 变量”。空白 final 变量必须在构造方法或静态代码块中初始化。

当使用 final 修饰基本类型变量时,不能对基本类型变量重新赋值,因此基本类型变量不能被改变。 但对于引用类型变量而言,它保存的仅仅是一个引用,final 只保证这个引用类型变量所引用的地址不会改变,即一直引用同一个对象,但这个对象完全可以发生改变

final修饰方法

final 修饰的方法不可被重写,如果出于某些原因,不希望子类重写父类的某个方法,则可以使用 final 修饰该方法。
final 修饰的方法仅仅是不能被重写,并不是不能被重载,因此下面程序完全没有问题。

1
2
3
4
5
public class FinalOverload {
// final 修饰的方法只是不能被重写,完全可以被重载
public final void test(){}
public final void test(String arg){}
}

final修饰类

final 修饰的类不能被继承。当子类继承父类时,将可以访问到父类内部数据,并可通过重写父类方法来改变父类方法的实现细节,这可能导致一些不安全的因素。为了保证某个类不可被继承,则可以使用 final 修饰这个类。

abstract关键字

抽象类

在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,那么这样的类称为抽象类。
在 Java 中抽象类的语法格式如下:

1
2
3
<abstract>class<class_name> {
<abstract><type><method_name>(parameter-iist);
}

其中,abstract 表示该类或该方法是抽象的;class_name 表示抽象类的名称;method_name 表示抽象方法名称,parameter-list 表示方法参数列表。
抽象类中可以存在抽象方法和非抽象方法

抽象方法

如果一个方法使用 abstract 来修饰,则说明该方法是抽象方法,抽象方法只有声明没有实现。需要注意的是 abstract 关键字只能用于普通方法,不能用于 static 方法和final方法或者构造方法中。
抽象方法的 3 个特征如下:

  1. 抽象方法没有方法体
  2. 抽象方法必须存在于抽象类中
  3. 子类重写父类时,必须重写父类所有的抽象方法

注意:在使用 abstract 关键字修饰抽象方法时不能使用 private 修饰,因为抽象方法必须被子类重写,而如果使用了 private 声明,则子类是无法重写的。

instanceof关键字

instanceof 是 Java 的一个二元操作符
它的作用是测试它左边的对象是否是它右边的类的实例,返回 boolean 的数据类型。
instanceof运算符使用格式如下:

1
( Object reference variable ) instanceof  (class/interface type)

左边操作元是对象,右边操作元是类。当左边对象是右面的类或其子类所创建的对象时,运算结果为true,否则为false。

this关键字

this代表当前对象:即每当创建一个对象时,对象的地址空间内会有一个this,这个this指向它自己。

this.属性名

当成员变量和局部变量重名,可以用关键字this区分

大部分时候,普通方法访问其他方法、成员变量时无须使用 this 前缀,但如果方法里有个局部变量和成员变量同名,但程序又需要在该方法里访问这个被覆盖的成员变量,则必须使用 this 前缀。

this代表当前对象,即在this.name = name 中后面的name代表局部变量name,this.name就指的是当前对象中的成员变量name。

this.方法名(参数列表)

this 关键字最大的作用就是让类中一个方法,访问该类里的另一个方法或实例变量。

this(参数列表)

this( ) 调用本类中另一种形式的构造函数,括号中可以有参数,如果有参数就是调用指定的有参构造方法。
在构造方法中使用时,必须是第一条语句。
在static方法中不能使用this关键字,static方法先于任何的实例(对象)存在。即static方法在类加载时就已经存在了,但是对象是在创建时才在内存中生成。而this指代的是当前的对象。

super关键字

super.父类成员

当子类的成员变量或方法与父类同名时,可以使用 super 关键字来访问。

1
super.member

其中,member 是父类中的属性。使用 super 访问父类的属性时不用位于第一行。

super.父类方法

如果子类重写了父类的某一个方法,此时,我们可以通过 super 来调用父类里面的这个方法。

1
super.member

其中,member 是父类中的方法。使用 super 访问父类的方法时不用位于第一行。

super调用父类构造方法

1
super(parameter-list);

parameter-list 指定父类构造方法中的所有参数,也可以无参。super( ) 必须是在子类构造方法的方法体的第一行。

break关键字

break 用于完全结束一个循环,跳出循环体。不管是哪种循环,一旦在循环体中遇到 break,系统将完全结束该循环,开始执行循环之后的代码。

1.使用 break 语句直接强行退出循环(break 不带标签)

可以使用 break 语句强行退出循环,忽略循环体中的任何其他语句和循环的条件判断。在循环中遇到 break 语句时,循环被终止,在循环后面的语句重新开始。

2.使用 break 语句实现 goto 的功能(break 带标签)

1
2
3
4
5
label: demo{
...
break label;
...
};

label 是标识代码块的标签。当执行这种形式的 break 语句时,控制权被传递出指定的代码块。
用标签(label)可以指定一个代码块,标签可以是任何合法有效的 Java 标识符,后跟一个冒号。加上标签的代码块可以作为 break 语句的对象,使程序在加标签的块的结尾继续执行。
标签语句必须和循环匹配使用,使用时书写在对应的循环语句的上面,标签语句以冒号结束。如果需要中断标签语句对应的循环,可以采用 break 后面跟标签名的方式。

1
2
3
4
5
6
7
8
9
10
11
12
public class GotoDemo {
public static void main(String[] args) {
label: for (int i = 0; i < 10; i++) {
for (int j = 0; j < 8; j++) {
System.out.println(j);
if (j % 2 != 0) {
break label;
}
}
}
}
}

continue关键字

continue 语句是结束本次循环强制执行下一次循环。
注意:continue 语句只能用在 while 语句、for 语句或者 foreach 语句的循环体之中,在这之外的任何地方使用它都会引起语法错误。
在循环体中使用 continue 语句有两种方式可以带有标签,也可以不带标签。

1
2
3
4
5
6
7
continue //不带标签

label: demo{
...
continue label;
...
//带标签

对于带标签的continue来说,跳出本轮循环,跳到标签的位置开始下一轮循环。
label 是标识代码块的标签。当执行这种形式的continue语句时,控制权被传递出指定的代码块。
用标签(label)可以指定一个代码块,标签可以是任何合法有效的 Java 标识符,后跟一个冒号。加上标签的代码块可以作为continue语句的对象,使程序在加标签的块的结尾继续执行。
标签语句必须和循环匹配使用,使用时书写在对应的循环语句的上面,标签语句以冒号结束。如果需要中断标签语句对应的循环,可以采用continue后面跟标签名的方式。

总结

类的关键字注意事项

类之前可以跟 public abstract final 只有内部类前可以加 static
public:在Java源文件中可以有多个类,但只能有一个public的类,并且public的类名必须与文件名相一致
abstract:关键字abstract修饰的类不能用new运算符创建对象。子类如果是一个非abstract类的话,子类必须重写父类的abstract方法,即去掉abstract修饰,并给出方法体。
final:关键字 final修饰的类不能被继承,即不能有子类

变量的关键字注意事项

变量之前可以跟 public protected default private / final static
权限关键字:详见关键字详解中的权限关键字
final:若用final修饰成员变量和局部变量后,变量的值不可改变,声明时必须指定常量的值。
static:⽤ static 声明的成员变量为静态成员变量,也成为类变量。类变量的⽣命周期和类相同,在整个应⽤程序执⾏期间都有效。
局部变量不能被权限修饰符和static修饰

方法的关键字注意事项

方法之前可以跟 public protected default private / final static abstract
权限关键字:详见关键字详解中的权限关键字
final:使用final修饰父类中的一个方法,那么这个方法不能被子类重写
static:静态⽅法能够直接使⽤类名.⽅法名 进⾏调⽤
abstract:只允许声明,不允许实现(即没有方法体)
不允许使用final和abstract同时修饰一个方法和类

注意:构造方法不能被 static、final、abstract、synchronized修饰。构造方法用于初始化一个新对象,所以用 static 修饰没有意义。构造方法不能被子类继承,所以用 final 和 abstract 修饰没有意义。多个线程不会同时创建内存地址相同的同一个对象,所以用 synchronized 修饰没有必要。