final在Java中可以引用变量,方法和类。有三个简单的规则:
final变量不能重新分配
final方法不能被重写
final类不能被扩展
用法
良好的编程习惯
一些开发人员认为,最好在可能的时候标记一个变量final。如果您有一个不应更改的变量,则应将其标记为最终变量。
如果将关键字 final 用于方法参数,则该关键字的重要用途。如果要强调某个方法不会更改其输入参数,请将该属性标记为final。
public int sumup(final List<Integer> ints);
这强调了summup方法不会改变int。
内部类访问
如果您的匿名内部类想要访问变量,则应将变量标记为 final
public IPrintName printName(){ String name; return new IPrintName(){ @Override public void printName(){ System.out.println(name); } }; }
该类不会编译,因为变量name不是最终的。
实际上,最终变量是一个例外。这些是局部变量,只能写入一次,因此可以确定为最终变量。有效的最终变量也可以从匿名类中访问。
final static 变量
即使final变量foonot为static,即使下面的代码是完全合法的,在这种情况下static也无法编译:
class TestFinal { private final static List foo; public Test() { foo = new ArrayList(); } }
原因是,让我们再重复一次,不能重新分配最终变量。由于foo是静态的,因此它在class的所有实例之间共享TestFinal。TestFinal创建类的新实例时,将调用其构造函数,因此将重新分配foo,而编译器不允许这样做。foo在这种情况下,初始化变量的正确方法是:
class TestFinal { private static final List foo = new ArrayList(); //.. }
或使用静态初始化程序:
class TestFinal { private static final List foo; static { foo = new ArrayList(); } //.. }
当基类实现一些派生类不应该更改的重要功能时,final方法很有用。它们也比非final方法快,因为不涉及虚拟表的概念。
Java中的所有包装类都是final类,如Integer、Long等。这些类的创建者不希望任何人可以将Integer扩展到自己的类中并改变Integer类的基本行为。使类不可变的要求之一是子类不能覆盖方法。最简单的方法是将该类声明为final。