Java中的修饰符可以修饰类,变量和方法,使软件程序更好地模拟现实世界。
顶层类 成员方法 构造方法 成员变量 局部变量
abstract Y Y N N N
static N Y N(实例相关) Y N
public Y Y Y Y N
protected N Y Y Y N
private N Y Y Y N
synchronized N Y(访问共享资 N N N
源的代码块)
native(本地的) N Y N N N
transient(暂时的) Y
volatile(易失的) Y
final(不可改变) Y Y N Y Y
局部变量只能够用final修饰
1.abstract修饰符
(1)abstract可以修饰类和方法
a.abstract修饰的类是抽象类,不能够被实例化,不能创建抽象类本身的实例,但是抽象类包含对象,包含它所有具体子类的对象;
b.abstract修饰的方法是抽象方法,没有方法体,用来描述系统具有的功能,但不提供具体的实现;
(2)抽象类未必有抽象方法,但是有抽象方法的一定是抽象类,如果一个类中有抽象方法而没有被定义为抽象类,则会出现编译错误;如果子类没有定义父类的抽象方法,则子类仍旧是抽象类;
(3)构造方法不能够是abstract的(构造方法不能什么都不做),static的方法(在类初始化时执行,对类执行初始化操作,不能够什么都不做)不能够是abstract的;<凡是和初始化相关的都不能什么都不做,不能定义成为abstract类型>
(4)抽象类中可以有非抽象的构造函数,对抽象类本身不能够进行实例化,但是可以创建抽象类的引用,让它引用一个具体子类的实例;
(5)abstract不能够和final连用,abstract表示类的抽象方法只有通过具体子类才能够实现,只有它的具体子类才能够被实例化,而fianl修饰的类不能够被继承,abstract方法没有方法体,必须被覆盖才能够实现,而final修饰的方法不能够被覆盖;
(6)当父类是具体类时,父类的对象包括父类本身的对象和子类的对象,当父类是抽象类时,父类的对象包括其所有具体子类的对象。
2.static修饰符
(1)static可以修饰成员变量,成员方法和代码块
a.静态变量可以通过类名访问,无需创建类的实例,所有实例共享;
b.静态方法可以通过类名访问,无需创建类的实例;
c.在虚拟机加载类的过程中,就会执行静态代码块,所有的静态代码块执行完毕后,在执行main方法。
(2)静态变量和实例变量
a.静态变量在内存中只有一份拷贝,位于运行时数据区的方法区中,在加载过程中Java虚拟机给静态变量分配一次内存,类初始化过程中完成静态变量的初始化操作,类加载后可以直接通过类名调用静态变量;
b.实例变量,每创建一个实例,会为实例变量分配一次内存,实例变量位于对象的堆区,各个对象的静态变量互相不影响。
(3)类的静态变量和静态方法归某个类所有,不依赖于类的特定实例,被类的所有实例共享,一旦类被加载,就可以通过类名调用静态变量或者静态方法,因为Java虚拟机可以在运行时的方法区找到它们;
(4)静态变量的作用:
a.类的所有实例共享,实例之间交流的共享数据;
b.所有类共享的常量。
以上(2)(3)(4)均将静态变量
(5)静态方法
(6)类加载之后,可以直接用类名调用静态方法,Java虚拟机会在运行时方法区找到静态方法的定义
(7)静态方法可以访问:
a.直接访问类中定义的静态方法和静态变量,JVM会在运行时类的方法区中找到他们;
b.通过对象访问类的实例方法和实例变量。
(8)静态方法不可以访问:
a.直接访问类的实例方法和实例变量,因为没有如果没有和具体的实例绑定,JVM无法到对象的堆区去找实例变量,只能到运行时类的方法区找,而实例变量在方法区没有定义(实例变量在对象的堆区定义),故JVM无法找到实例变量的声明。
b.不可以使用this和super,this是当前对象的引用,super是父类对象的引用。
注意,之所以static方法不能访问实例变量是因为JVM不知道在堆区中找哪个对象,在不确定对象的时候,只能够去方法区去找,方法区中又没有实例变量的定义。
(9)实例方法可以访问:
a.静态变量
b.静态方法
上述两项所有实例共享,必然可以访问
c.实例变量
d.实例方法
访问具体实例的变量和方法,因为实例方法已经与具体的实例相绑定,故对象已经确定,JVM知道去那个对象的堆找实例变量和实例方法,故实例方法中可以直接调用实例变量和实例方法。
(10)静态方法必须被实现
静态方法是这样一种方法,它表示某个系统(类)的特殊功能,特殊在这些功能不依赖类的具体实例,不依赖类的子类,因此,静态方法必须提供实现,不能被定义为abstract
static和abstract是矛盾的,前者必须自力更生,必须字节实现,abstract必须依赖子类实现。
(11)main方法
main必须被定义成为static,因为这样才能够在类被加载后就能够调用,而不用创建类的实例
(12)方法(无论是静态方法还是实例方法)都位于运行时类的方法区,静态变量也位于运行时类的方法区,实例变量位于对象的堆区。
以上是关于静态方法
(13)静态代码块在类被加载过程中执行,且只能够执行一次,在加载过程中执行静态代码块,加载结束后实行main方法。
(14)构造函数用于初始化对象,静态代码块用于初始化类,即为类的静态变量赋初始化值;
(15)静态代码块不能直接访问类的实例变量和实例方法。
3.final修饰符
(1)final修饰的类不能够被继承,方法不能够被子类覆盖,变量是常量;
(2)final可以修饰静态变量,实例变量和局部变量;
(3)final修饰的变量必须显示地初始化,静态变量可以在声明时或者静态代码块中初始化,实例变量可以在声明时或者构造函数中初始化;
(4)final只能够修饰实例方法,不能够修饰构造方法;
(5)用private修饰的方法不能够被继承,因此不能够被覆盖(被覆盖的前提是要被继承),因此相当于final;
(6)一个final修饰的变量只能够被赋值一次;
(7)如果一个引用变量用final修饰,那么这个引用变量只能够引用一个对象,但是对象的属性可以改变;
(8)继承的弱点是打破对象的封装,子类可以访问父类的实现细节,还可以通过方法覆盖来修改父类的实现细节。