本文共 1820 字,大约阅读时间需要 6 分钟。
<Tim's type>
作为Java编程语言中的关键修饰符,final具有广泛的应用场景。掌握这些概念对于提升你的编程能力至关重要,特别是在面对对象的封闭性和单向性问题时。
final修饰的域,指的是在类中定义的常量或不允许更改的变量。在Java中,final修饰的域具有以下特点:
必须初始化:当定义一个final域时,必须在声明或构造器(或构造块)中进行初始化操作。这是因为final域一旦初始化后就无法改变。
引用不变性:当一个引用被final修饰时,意味着该引用的指向对象不能被改变。即使对象中的指针可以用数组修改,引用本身仍然保持指向原先对象。
static final的特殊性:将final与static一起使用时,特别强调该域的值不会随着对象的创建而改变,这也是static(静态的)特性的体现。
让我们来看一个典型的例子:
public class FinalData { private static final int VALUE_TWO = 99; // 被static final修饰的域 public static final int VALUE_THREE = 39; // 被public和static final修饰的域 private final int i4 = rand.nextInt(20); // 被final修饰的域}
在这个例子中:
VALUE_TWO
和 VALUE_THREE
都被static和final修饰,说明它们是常量。i4
被final修饰,说明它一旦初始化就无法改变,且不是静态的。在Java中,如果方法参数被标记为final,那么意味着调用该方法的代码无法修改该参数所指向的对象。如果参数是一个引用类型(如对象或数组),则用户不能修改其引用。如果是原始类型(如int),则可以通过final参数实现常量行为。
例如:
public class FinalArguments { void with(final Gizmo g) { // g = new Gizmo(); // Illegal — g是final } void without(Gizmo g) { g = new Gizmo(); // ok — g不是final g.spin(); }}
在这个例子中:
with
接受一个final参数g
,意味着在该方法内部,g的引用不能被改变。without
不接受final参数,所以可以修改g的引用。需要注意的是,不仅对象必须是final,数组推断的参数也有类似的限制。
在Java中,方法可以被修饰为final,意指该方法不能被子类重写(覆盖)。此外,所有的private方法,只要没有明确写出final,其实也会隐含地成为final。因此,如果你想防止方法被重写,建议使用private并明确写出final。
例如:
public class Sample { public static final void doSomething(); // 作为静态方法被final修饰 private final void doSomethingElse(); // 隐含的final}
如果子类试图重写doSomething或doSomethingElse,就会得到编译错误。
将final应用于类时,意味着该类不能被另一个类继承。这样可以确保类的封闭性,减少削弱对单继化设计模式的支持。例如:
public class Base { // 不可继承的属性}public class Derived extends Base { // 这样是不允许的,因为Base是final}
如果你真的需要继承Base类,可以将其换成abstract或public修饰。
Java的final修饰在不同场景中发挥着重要作用,它的使用可以帮助你保护类的封闭性、防止方法被重写,以及确保常量和引用不变性。在编写代码时,合理使用final修饰可以让代码更加安全可靠。
转载地址:http://zqytz.baihongyu.com/