1. final类
final类不能被继承,因此final类的成员方法没有机会被覆盖,默认都是final的
优点:
- final类的对象实例是只读的
- 在多线程环境下安全的共享,不用额外的同步开销
public final class FinalClass {
private int index = 1;
public int get() {
return index;
}
}
public class ChildFinalClass extends FinalClass { // 这种写法不允许,编译软件也会报错
}
2. final变量
- final可以修饰静态变量、实例变量和局部变量
- final变量需要为其指定初始值,值一旦给定就无法改变
- final修饰基本数据类型,值不能改变
实例:
- final修饰引用类型,引用变量不能改变(即指向对象的地址不能改变),但是对象可以改变
测试举例:
package entity;
public class Person {
private int index;
public int get() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
}
import entity.Person;
public class FinalTest {
public static void main(String[] args) {
System.out.println("final修饰引用类型");
final Person person1 = new Person();
person1.setIndex(100);
System.out.println("当前index = " + person1.get() + " ,当前对象hashCode = " + person1.hashCode());
person1.setIndex(200);
System.out.println("当前index = " + person1.get() + " ,当前对象hashCode = " + person1.hashCode());
System.out.println("--------------");
System.out.println("index不同说明对象person1改变了");
System.out.println("对象person1的hashCode相同说明person1指向的对象没改变");
}
}
输出结果:
final修饰引用类型
当前index = 100 ,当前对象hashCode = 356573597
当前index = 200 ,当前对象hashCode = 356573597
--------------
index不同说明对象person1改变了
对象person1的hashCode相同说明person1指向的对象没改变
3. final方法
final方法不能被重写
如果一个类不允许其子类覆盖某个方法,则可以把这个方法声明为final方法,好处:
- 把方法锁定,防止任何继承类修改它的意义和实现
- 高效:编译器在遇到调用final方法时候会转入内嵌机制,大大提高执行效率
需要注意的一点是:因为重写的前提是子类可以从父类中继承此方法,如果父类中final方法同时访问控制权限为private,将会导致子类中不能直接继承到此方法,因此,此时可以在子类中定义相同的方法名和参数,此时不再产生重写与final的矛盾,而是在子类中重新定义了新的方法。
public class Parent {
/**
* private修饰方法,子类不能继承
* */
private final void get1() {
}
/**
* final方法,子类不能继承
* */
public final void get2() {
}
}
public class Child extends Parent {
/*
* 父类中的方法是private修饰,子类不能继承
* 这个是子类自己的方法
*/
public static void get1(){
System.out.println("子类 get1");
}
public void get2(){ // 报错,需改成 not final
}
}
private 子类不能继承,同名是新建的;
final 子类同名报错;