讲在前面:成员访问控制修饰符 public/protected/default/private的作用就不解释了,重点解释static
一、类修饰符:public/final/abstract
final修饰的类不能再有派生类,意思是类的树形结构的叶子节点。
abstract修饰的类是抽象类
public修饰的类:一个java文件只能有不超过一个的public类,而且若有public类,文件名必须和public类名相同
二、成员变量修饰符:public/protected/default/private、static、final
变量有类变量、实例变量、局部变量之分,而变量的类型又有引用类型与基础类型之分,还有是否为final之分,所以组合起来一共有12种可能,这需要多用多写来记住。
static修饰符是用于标明成员变量、方法、内部类、初始化块这四种成员是属于类的本身,在类加载过程中就会被创建,生命周期同类的生命周期,俗称“静态”,没有static修饰的四种成员生命周期与引用他们的对象相同。所以static的成员用类名来访问。
static修饰的范围内不可以直接调用非static成员, static修饰的范围内不可以出现this,因为this代表当前类的一个对象。static成员调用非static成员可以通过新建一个对象来访问。
一个类在使用之前要经过 类加载、类验证、类准备、类解析、类初始化等几个阶段,类变量在类准备过程中就创建好。
final变量,一旦有了初始值,就不能被重新赋值, 而类的成员变量在类初始化或对象初始化时会被分配内存并分配默认值,所以final成员变量若不显示指定初始值,就无法使用了! final修饰的成员变量必须由程序员显示指定初始值
final类变量:必须在静态初始化块中指定初始值 或 在声明该类变量时指定初始值
final实例变量:必须在非静态初始化块 或声明该实例变量 或构造器中指定初始值
final局部变量:系统不会对局部变量进行初始化。
final引用类型变量:由于引用类型变量的值只是一个引用,而不是实际的成员内容,所以final只能保证引用的地址不会改变,但是引用的成员保存的值却可以改变。若想真正创建不可变类,则必须将其所有包含的可变成员变量保护起来。需要把可改变的内存空间保护起来,即限制其访问,不让外部代码获取该内存空间的引用。而是新建一个内存空间将值copy一份作为返回。
final 还可用作宏替换
不可变类是一种设计的模式,可以设计出实例内容不可被改变的类,创建不可变类的时候要小心成员变量中的引用变量,因为他们仅仅是引用!。不可变类始终处于初始化状态,对不可变类的实例控制会比可变类简单,不可变类的好处多多,当然也有一定弊端,具体内容不再赘述,只是作为了解(学习不可拘泥于细节)
String类的设计就是不可变类,那为什么还可以给String多次用“=”赋值呢?这是java语法内嵌内容,每次给String赋值,都会重新创建一个String对象再返回其引用,这种设计最大考虑应该是为了效率和安全。
题外话,java会使用常量池来管理曾经使用过的常量(直接量),同样字符串常量(如 “keifsafafasda”、“”)也会被常量池管理,也就是说对于两个相等的直接量如5 和5,java不会创建两片内存区域来保存它们,而是在第一次使用直接量时把它存在常量池中,第二次使用它时直接将使用的引用指向已经存在的直接量,通俗的讲就是常量池中没有5,就创建它,常量池中有了5,就引用它。所以将同一个直接量分别赋值给两个两个引用时,这两个引用实际上指向了同一片内存区。
final并不同于C里面的常量,不可混淆。思考语言的问题一定要从底层本质去思考,不可以想当然。
三、方法修饰符:public/protected/default/private、static、final/abstract
static 如上
final/abstract:final修饰的方法不可以被重写,abstract方法是抽象方法
方法重载:Overload 方法重写:Override
四、构造方法修饰符:public/protected/default/private,使用后三者可以对构造方法进行不同程度的隐藏,使创建该类的实例收到一定限制,可以应用于一些特殊的场景:例子 java单例类。说点题外话,构造器的重载要使用this引用(重用旧构造器代码,提高程序可维护性),重写可能会使用super引用父类构造器。对象的创建在执行构造器之前就已完成,执行构造器返回一个该对象的引用。