publicclassBlankFinal{ privatefinalint i = 0; // Initialized final privatefinalint j; // Blank final privatefinal Poppet p; // Blank final reference
// Blank finals MUST be initialized in the constructor: publicBlankFinal(){ j = 1; // Initialize blank final p = new Poppet(1); // Initialize blank final reference }
publicBlankFinal(int x){ j = x; // Initialize blank final p = new Poppet(x); // Initialize blank final reference }
publicstaticvoidmain(String[] args){ new BlankFinal(); new BlankFinal(47); } }
publicclassFinalOverridingIllusion{ publicstaticvoidmain(String[] args){ OverridingPrivate2 op2 = new OverridingPrivate2(); op2.f(); op2.g(); // You can upcast: OverridingPrivate op = op2; // But you can’t call the methods: //! op.f(); //! op.g(); // Same here: WithFinals wf = op2; //! wf.f(); //! wf.g(); } } // output: // OverridingPrivate2.f() // OverridingPrivate2.g()
If a method is private, it isn’t part of the base-class interface. It is just some code that’s hidden away inside the class, and it just happens to have that name.
finalclassDinosaur{ int i = 7; int j = 1; SmallBrain x = new SmallBrain();
voidf(){ } }
//! class Further extends Dinosaur {} // error: Cannot extend final class ‘Dinosaur’ publicclassJurassic{ publicstaticvoidmain(String[] args){ Dinosaur n = new Dinosaur(); n.f(); n.i = 40; n.j++; } }
final class 的 field 可以不是 final 的,但是 final class 里面的 method 都隐示为 final method。因为 final class 就是为了防止被继承,都不被继承了,对应的方法都不能重写也是合理的。
和前面的章节一样,这里的默认 final 也是语义上的,并不会在字节码中体现出来。
final caution
例举了一些老的 Java lib 实现 Vector 和 Hashtable 说明,使用 final 修饰方法的时候要谨慎,你完全不知道其他人会怎样使用你的代码。