赞
踩
final在Java中是完结器,表示不可改变的最终形态。final应用于类、方法、和变量时的意义时不同的,但本质是一样的。
下面一一介绍final的作用。
final修饰变量,那么此变量即使常量,只能赋值一次,但是final修饰局部变量和成员变量却有所不同。
注意:final修饰的变量不能被赋值这种说法是错误的,严格来说,final修饰的变量不可改变,一旦获得了初始值,该final变量的值就不能被重新赋值。
代码演示:
public class FinalTest { // 静态常量 final static int a = 12; // 直接赋值 final static int b; // 空白final变量 // 静态代码块 static { b = 20; } // 实例常量 final int c = 30; // 直接赋值 final int d; // 空白final变量 // 构造方法 FinalTest() { d = 33; // d = 22; // 第二次赋值,编译时会报错 } void others() { final int e; e = 100; // 只能赋值一次 System.out.println(e); final int f = 111; // 声明的同时赋值 } }
注意上方代码:
当使用final修饰一个基本类型变量时,不能对基本类型变量重新赋值,修饰过后就是不能改变。但是对于引用类型变量来说,它保存的仅仅是一个引用,final只是保证这个引用类型变量所引用的内存地址不会发生改变,如果引用同一个对象,那么这个对象完全可以发生改变。
换个理解方式,就是说final保证的是内存地址的指针指向不会改变。
代码演示和讲解上述和意思:
public class Person { private int age; // 无参构造器 public Person() { } // 有参构造器 public Person(int age) { this.age = age; } // 由于age变量私有化,所以通过setter和getter使得子类可以进行方法age变量 public void setAge(int i) { i = age; } public int getAge() { return age; } }
public class FinalReferenceTest { public static void main(String[] args) { // 使用final修饰一个引用类型的数组 final int[] iArr = { 5, 6, 12, 9 }; System.out.println(Arrays.toString(iArr)); // 对数组元素进行排序 Arrays.sort(iArr); System.out.println(Arrays.toString(iArr)); // 对数组元素进行赋值,不会报错 iArr[2] = -8; System.out.println(Arrays.toString(iArr)); // 如果对iArr数组重新进行赋值,则是错误的 // iArr = null; // 使用final修饰对象 final Person p = new Person(45); // 改变Person对象的age实例变量,不会报错 p.setAge(23); System.out.println(p.getAge()); // 如果对p重新进行赋值,则是错误的,例如: // p = null; } }
对于引用类型变量来说,final保证的只是这个引用类型变量所引用的地址不会改变,也就是说final保证的是这个对象,并不是真正的“内容”。
final修饰的方法不可以被重写,如果在继承当中不希望子类继承父类的某个方法,则可以使用final修饰父类中的方法。如果子类试图重写该方法,将会引发编译错误。
注意:
代码演示:
public class FinalPrivateMethod {
final void method1() {
}
private final void method2() {
}
}
public class Zi extends FinalPrivateMethod{
// 父类中的method1方法被final修饰,子类重写会发生编译报错
// public void method1() {
//
// }
// 父类中的method2方法访问权限时private,子类再次定义method2方法
// 不算是方法重写,而是新定义一个方法
public void method2() {
}
}
上述的父类和子类1虽然有着相同的test方法,但是子类不算是重写父类的test方法,即使父类的test方法使用了final修饰,子类依旧可以定义test方法。
final修饰的方法只是不可以被重写,但是可以重载!
因此像下面这样写也是没有问题的:
public class FinalOverload {
// final 修饰的方法只是不能被重写,完全可以被重载
public final void test(){}
public final void test(String arg){}
}
但凡被final修饰过的类不可以被任何其它的类所继承,无需代码演示了,因为肯定会发生编译报错。
final修饰过的变量一旦初始化则不可改变,这里的不可改变是指对基本类型变量来说是它的值不可以改变,而对对象引用类型变量来说是它的引用不可再变。
注意变量初始化的位置:(上方有代码演示)
final修饰过的类表示该类无法被任何其它的类继承,而对于final修饰过的类来说,该类中的成员可以定义其为final,也可以不是final。对于方法而言,即使没有final修饰,自然也算是final方法,也可以明确的给该方法加上一个final修饰符,这显然没有什么意义。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。