final类
被final关键字修饰的类就是fianl类,final类无法被继承。final类的所有方法在默认情况下都会是final级别,因为类都无法被继承,方法自然也无法被继承。但是fianl类的域可以根据自己意愿选择是否为final。
public final class FinalTest {
}
final方法
被final修饰的方法就是final方法,用final修饰方法的原因无非两个,第一就是将方法锁定,让其无法被继承以防止任何继承类修改它的含义。第二是出于效率的考虑(解释暂无)
final和private关键字
类中所有的private方法默认情况下都是final级别的,也就是无法被继承,因为private关键字将方法的权限限定在了当前类中,其他类是无法直接访问这个方法的。
这里有一点容易造成疑惑,那就是即使private方法是fianl级别的,表示它无法别继承,但是如果我们继承这个类,我们发现,在子类中似乎仍然可以覆盖这个方法,注意这里其实并不是覆盖,而只是在子类中创建了一个和父类有着相同名字和参数列表的方法。它并不是从父类中继承而来的。
覆盖只有某一个方法是父类接口的一部分时才能称之为覆盖,也就是说,如果子类继承了父类,那么在创建对象的时候能够向上转型并且调用到父类的原始方法。但是很明显,在子类中是绝对无法调用到父类中的private方法的
final数据
final数据有两种形式
- 以基本数据类型修饰的数据
- 以引用类型修饰的数据
以基本数据类型修饰的数据用来表示常量,而且和static关键字联合使用,定义时必须对其进行初始化。
public static final double PAI =3.14;
带有static和final的编译时常量的命名应该全部使用大写,字与字之间使用下划线分开。
对于基本数据类型的final,它的值在程序中是不能改变的。除非去定义它的地方进行修改。
引用数据类型的final则表示的是这个引用的地址不能改变,也就是说一旦引用类型的final指向了一个对象,就不能改变而指向另外一个对象了。但同时final指向的这个引用虽然不能改变,但是引用指向的这个对象本身里面的内容是可以改变的。
注意:我们不能因为某个数据是final的,就认为在编译期间就能知道它的值。实际上他的值是可以在运行时给出的。
static Random random = new Random(20);
public static final double PAI = random.nextDouble();
这种情况下,PAI的值只有在运行时才被确定。
但是普遍情况下我们使用定义时就赋值的常量的情况较多。
一个即使static又是final的域占用一段不能改变的存储空间。