Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
';最终';Java中类的修饰符_Java_Class_Extend_Final - Fatal编程技术网

';最终';Java中类的修饰符

';最终';Java中类的修饰符,java,class,extend,final,Java,Class,Extend,Final,我有一个简单的问题。我有一个习惯,就是每节课都是“最后一节课”,当然,除非需要另一节课来延长 这是个坏习惯吗?好习惯?这有关系吗? 我理解修饰符对类的影响 提前多谢 编辑: 下面是一个示例代码。该类不会被任何其他类扩展 public final class Application { /** * Starts the application. * * @param arguments arguments provided from command-lin

我有一个简单的问题。我有一个习惯,就是每节课都是“最后一节课”,当然,除非需要另一节课来延长

这是个坏习惯吗?好习惯?这有关系吗? 我理解修饰符对类的影响

提前多谢

编辑: 下面是一个示例代码。该类不会被任何其他类扩展

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();
    }
}

你的问题没有确切的答案。这取决于你所写课程的目的。有些应该本质上是最终的,而其他不应该,除非您想明确禁止子类化

如果您只是自己编程,那么我认为这不会有任何区别,每次您知道或需要对某个对象进行子类化时,您都会删除
final
修饰符


总之,类的
final
修饰符它通常是向其他人提示如何使用您的类,而不是一个真正的好/坏习惯。

它对HotSpot没有影响,但我不确定其他运行时系统。我从不使用它,因为它似乎没用。虽然变量中的final(在热点中也没有效果)可以阻止您更改您不想更改的值,但对于类,您真的没有同样的担心


不过,在热点地区,它曾经很重要。这可能对Android和Dalvik之类的东西很重要。

我认为这是一个坏习惯,因为这意味着你没有仔细考虑这个决定。不要让事情成为最终结果的要点是,您可以在不更改原始代码的情况下进行子类化和更改。你打破了这个习惯。

这是一个好习惯。将final类更改为nonfinal不应破坏任何代码。将非final类更改为final可能会破坏某些代码。

通常这不是一个好主意。如果这些类仅限于您的项目,那么可以这样做。当你看到需要扩展某些课程时,他总是可以让它们成为非最终课程。

我要说的是坏习惯,原因如下:

  • 您尚未指定该类为最终类的任何特定需求
  • 你违反了法律。类应该为扩展打开,但为修改关闭
  • 最终确定的类可能很难用模拟框架进行测试
例如:

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

private static final class Fruit {

}
…将产生

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
当然,有一些有效的场景可以完成类。例如,您的类是不可变的。

程序员(甚至Java大师)都不同意这一点

Josh Bloch设计了Java集合库Java.Math,
assert
,是Google的首席Java架构师(或者在他们雇用Gosling之前),他在书中的“有效Java”一节专门讨论了这个问题。我同意他说的话:

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

他指出,子类化不是为它设计的,这常常会导致灾难

此外,为继承而设计是昂贵的

  • 它给你的班级的能力设置了很大的限制
  • 您必须编写更多的文档,以便子类作者知道类如何在内部使用公共方法
  • 你必须测试它。这需要测试编写子类
  • 你总是可以改变主意,做一些非最终的事情。你不能让过去不是最终的东西成为最终的


    阅读“有效的Java”,它使这个论点更加令人信服。这也会让你成为一名更好的程序员

    这取决于谁将使用你的类。有人知道单元测试的各种模拟库是否都符合“最终”标准吗?@Paulo我正在为一个游戏编写服务器,我不打算向公众发布代码,因此,我是唯一使用该代码的人。如果您试图扩展
    final
    类而没有意识到您正在扩展它,这可能会很糟糕。@fireshadow52我没有在我知道需要扩展的类上添加“final”修饰符。添加不必要的“final”很重要类上的修饰符会使代码用户的生活变得非常困难。从安全的角度来看,我读到嵌套类的“final”对发出的字节码没有影响。即使你是“独自”编程,在单元测试非琐碎代码时,你的生活可能会变得非常艰难。你说的“你没有仔细考虑决定”是什么意思?正是我所说的。你把它描述为一种习惯,这意味着你没有做出一个明确的,有意识的决定,这个类永远不应该被覆盖。但是,不把事情标记为最终的也是一个决定。区别在于,如果它是最终的,那么在子类化时,您不需要测试/记录行为。我是否误解了您,或者您是否用最后一句话反驳了您的第一句话?除非您正在编写API代码,并且API用户无法修改您的源代码。@Steve Inheritation被高估了。API用户应该使用composition。从有效的Java“继承的设计和文档,或者禁止继承”,我认为您不应该模仿实现类。只有为继承而设计的类。如果可以用mock对代码进行测试,那么将代码绑定到特定的实现是没有意义的。此外,扩展与子类化不是一回事。每个公共类都可以以基于组合的方式使用,但“继承违反了封装”,因为如果重写一个方法,它可能会更改其他方法的行为,因此必须为继承进行设计。看见