Skip to content

修饰符

3.9 权限修饰符

  • Java 提供了public, protected, 默认, private四种访问修饰符。
  • 通过访问修饰符来提高程序的安全性和可维护性。
修饰符本类中同包类中 (本包)子类中其他包中 (不同包中的所有类)
public可以可以可以可以
protected可以可以可以不可以
默认可以可以同包可以不可以
private可以不可以不可以不可以

3.10 非权限修饰符

3.10.1 静态

  • Java 中使用static关键字来标识静态。

  • 可以使用静态来修饰变量、方法、内部类和代码块。

3.10.1.1 静态变量

  • 也称为类变量

  • 随着类的加载而被加载到方法区中,在其内部自动赋默认值

  • 静态变量优先于对象而存在,故静态变量可以不通过对象,直接通过类来调用(通过对象调用也是可以被理解的)。

  • 该类所产生的所有对象实际上保存该静态变量在静态区中的地址。

  • 静态变量被该类的所有对象所共享。

静态内存

路标 -> Java 内存分区

注意

  • 静态变量不能定义在构造代码块中

  • 在构造代码块中可以对静态变量赋值

Input

java
class OneClass {
  static int iSta;

  {
    iSta = 10;
  }
}

3.10.1.2 静态方法

  • 也称为类方法

  • 在类加载的时候加载到方法区中的静态区。只存储在静态区,方法被调用时在栈内存中执行。

  • 静态方法先于对象而存在,静态方法可通过类名或对象调用,不能直接使用本类中的非静态方法和非静态属性。

注意

  • 静态方法中不能定义静态变量

  • 静态方法中不能直接调用类中的非静态方法

  • main()不能使用thissuper

  • 静态方法不能重写

  • 父子类中可以存在方法签名一致的静态方法 父子类中存在方法签名完全一致的方法,两者或均被static修饰或都不被static修饰

  • 静态方法可以被继承

  • 类只加载一次,只在第一次使用时加载到方法去,加载之后不再移除

3.10.1.3 静态代码块

  • 类被第一次真正使用(创建对象/调用方法)时执行一次

  • 先父后子,先静后动

Input

java
class OneClass {
  static int i = 5; // Warning: Variable 'i' initializer '5' is redundan

  static {
    i = 7;
    i += 7;
  }
}

Class AnotherClass {
  static {
    i = 7;  // Warning: The value 7 assigned to 'i' is never used 
    i += 7; // Error: Illegal forward reference
  }

  static int i = 5;
}
  • OneClass
    首先编译int i,后续针对i的操作有效。

  • AnotherClass
    编译到i = 7;时检查之前代码中是否定义过变量i,若上文不存在该变量则将其暂时标记为一个成员变量。
    此时这个变量i不真实存在,后续对i的操作无效。
    直到找到与标记名称i一致的成员变量时,才会将标记的i真正赋值。

3.10.2 最终

final关键字可以用来修饰数据(成员变量),方法(成员方法)和类。

3.10.2.1 常量

final修饰数据时,这个数据称为常量。定义后不可修改

注意

  • 成员常量需要在对象创建完成前进行赋初值,且只能赋值一次。赋值时机可以为:声明变量时直接赋值;构造函数中赋值;类的初始代码块中赋值。
  • 若常量是静态常量,需要在类加载之前进行赋值。赋值时机为:声明变量时直接赋值;静态初始代码块中赋值。
  • 若常量类型为基本数据类型,其实际值不可变;若常量类型为引用数据类型,其地址不可变
  • 方法中的常量,需要在使用前赋值。
  • 可以保证线程安全。

3.10.2.2 最终方法

final修饰方法时,这个方法称为最终方法。

注意

  • 最终方法不能被重写,可以被重载,可以被继承
  • 不允许修饰构造方法。

3.10.2.3 最终类

final修饰类时,这个类称为最终类。

注意

  • 最终类不能被继承

  • 最终类不能拥有匿名内部类

3.10.3 抽象

在 Java 中,为了体现开闭原则引出了抽象的概念,利用抽象可以做到面向抽象编程。利用面向抽象编程,我们在编写代码时在宏观层面不关心类中具体实现而只关心类的操作。

3.10.3.1 抽象方法

  • 当需要子类存在一些名称一致但细节不同的方法时,可以在父类中事先声明出这些方法。

  • 此时的声明行为无需为其编写方法体,使用这种方式构成的方法称为抽象方法,使用关键字abstract修饰。

注意

  • 抽象方法所在类必须是抽象类

  • 抽象方法必须被重写,子类继承抽象类后必须重写其中的抽象方法

  • 抽象方法之间可以重载(重载只关注方法名和参数列表)

  • 抽象方法的权限是默认,要求子类必须同包

注意

  • 抽象方法不能使用static修饰(静态方法隶属于类)

  • 抽象方法不能使用final修饰(最终方法无法被重写,不符合抽象方法的规则)

  • 抽象方法不能使用private修饰(造成子类不可见,进而无法重载)

  • 最终类不能是抽象类(最终类无法被继承,进而其方法也无法被重载)

3.10.3.2 抽象类

abstract修饰的类称为抽象类。

注意

  • 抽象类不能创建对象

  • 抽象类中存在构造方法

  • 抽象类中可以存在非抽象方法和属性