Java中类的'final'修饰符

Mar*_*ius 8 java final class extend

我有一个快速而简单的问题.我习惯于让每个班级都"最后",除非当然,它需要由另一个班级延长.

这是一个坏习惯吗?一个好习惯?它甚至重要吗?我理解修饰符对类的影响.

非常感谢提前!

编辑:这是一个示例代码.任何其他类都不会扩展此类.

public final class Application {

    /**
     * Starts the application.
     * 
     * @param arguments arguments provided from command-line
     */
    public static void main(String[] arguments) {
        LaunchUtilities util = new LaunchUtilities(new EventHandler());

        try {
            util.addListener(43594);
        } catch (IOException ioe) {
            Logger.getLogger(Application.class.getName()).log(Level.SEVERE, "Could not bind a port to a listener!", ioe);
        }

        util.start();
    }
}
Run Code Online (Sandbox Code Playgroud)

Phi*_* JF 8

程序员(甚至Java大师)对此持不同意见.

设计Java Collections库的Josh Bloch,java.Math,assert并且是谷歌的首席Java架构师(或者在他们雇用Gosling之前),他的一本书"Effective Java"专门讨论了这个问题.我跟他说的一样:

第17项:继承的设计和文件,或禁止它

他指出,为非专门设计的类的子类通常会导致灾难.

此外,继承的设计是昂贵的.

  1. 它对你的班级可以做的事情设置了很大的限制
  2. 您必须编写更多文档,以便子类作者知道类在内部如何使用公共方法
  3. 你必须测试它.这需要测试编写子类

你总是可以改变主意,做出非决定性的事情.你不能做出最终用于不是最终的东西.

阅读"Effective Java",它使这个论点更加引人注目.它还将使您成为更好的程序员.


emo*_*ory 7

这是一个好习惯.将最终类更改为非最终类不应该破坏任何代码.将非最终类更改为final可能会破坏一些代码.


hoi*_*loi 7

我会说坏习惯,原因如下:

  • 您没有指定任何特定的类是最终的需要.
  • 您违反了开放/封闭原则.类应该是可以扩展的,但是关闭以进行修改.
  • 使用模拟框架很难测试最终的类.

例如:

public static void main(String[] args) {
    final Fruit mockFruit = Mockito.mock(Fruit.class);
}

private static final class Fruit {

}
Run Code Online (Sandbox Code Playgroud)

......会屈服......

Exception in thread "main" org.mockito.exceptions.base.MockitoException: 
Cannot mock/spy class org.foo.Foo$Fruit
Mockito cannot mock/spy following:
  - final classes
  - anonymous classes
  - primitive types
Run Code Online (Sandbox Code Playgroud)

当然,有最终确定类的有效方案.例如,您的类是不可变的.


Sco*_*son 5

我会说这是一个坏习惯,因为这意味着你没有考虑决定.不做决定的重点是你可以在不改变原始代码的情况下进行子类化和进行更改.你打破了这个.