【问题标题】:Reasoning for making a method final使方法最终化的推理
【发布时间】:2011-04-18 21:10:03
【问题描述】:

抱歉,在这里快速提问,刚刚在我的笔记中发现了一些关于使方法最终化的内容我不明白。我的笔记声称你应该为此制定一个最终的方法:

无法强制执行不变量。

一个字符串应该表现得像一个字符串。

我真的不明白这是什么意思。有人可以帮我分解一下吗?非常感谢。

【问题讨论】:

  • 我认为这是一件好事的主要情况是当您在类的构造函数中使用该方法并且您有理由相信有人可能会继承您的类。

标签: java methods final


【解决方案1】:

我猜应该说“使强制执行不变量成为可能”。基本上,如果有人可以覆盖一个方法,那么他们就可以改变影响你的类的不变量的行为。

【讨论】:

  • 但是如果是final的话,不是不能强制不变量吗?如,您将无法编辑该方法,因此不可能有变体?我有点困惑!
  • 如果它是最终的,那么你不能改变它的实现,因此你可以断言这个方法做了你期望它做的事情(一个不变量)。
【解决方案2】:

通常有两个原因使方法最终确定,性能和设计。当一个方法是最终的,它可能是内联的。在 HotSpot 编译(JDK 1.1.x)之前,这些方法通常在编译时内联,而对于 HotSpot,它们在运行时内联,除非编译器可以保证内联方法总是与使用它的代码一起编译。 我知道将局部变量或参数设为 final 有两个原因。第一个原因是您不希望代码更改局部变量或参数。许多人认为更改方法内的参数是不好的风格,因为它会使代码不清楚。作为一种习惯,一些程序员将所有参数设置为“最终”以防止自己更改它们。我不这样做,因为我发现它使我的方法签名有点难看。

第二个原因出现在我们想要从内部类中访问局部变量或参数时。据我所知,这就是最终局部变量和参数在 JDK 1.1 中被引入 Java 语言的实际原因。 Source

【讨论】:

  • 此内联发生在“即时”编译时,例如虽然已经在运行程序,但已经在 Hotspot 之前。 Hotspot 现在只会在它认为会带来一些性能提升的情况下进行内联,在它运行该方法几次之后。并且 Hotspot 足够智能,也允许内联非最终方法,只要还没有任何子类覆盖此方法。 (如果这被证明是错误的,它会在以后取消内联它们。)
【解决方案3】:

是的,基本上做任何事情都意味着你不能改变它。出于同样的原因,可以在一个类中设置一个最终方法,以使其他子类无法覆盖该方法的功能。这适用于您绝对希望这一功能总是做这件事的情况。

【讨论】:

    【解决方案4】:

    如果你的笔记阅读起来可能会更有意义:

    最后一种方法可以可能强制执行不变量。

    换句话说,最终确定一个方法可确保它返回您想要的值,而不是返回其他人错误地认为应该是的覆盖值。

    【讨论】:

      【解决方案5】:

      那些注释没有多大意义——我认为不可能应该是“可能的”。这个想法是,如果您不希望子类更改方法的行为,则可以将该方法标记为 final 并且它不能被覆盖。与将整个类标记为最终类相比,这提供了更细粒度的控制。

      【讨论】:

        【解决方案6】:

        基本上,如果您将方法设为最终方法,则不能在子类中覆盖该方法。

        如果您的应用程序的行为依赖于以某种方式完全运行的特定方法,并且您不希望其他开发人员出现并更改此行为,那么您可以使用 'final '关键字。

        【讨论】:

          【解决方案7】:

          String 在创建时是不可修改的。这意味着它的所有内部字段都被声明为 final,并且它没有提供更新其内部内容的方法。因此,当您将字符串声明为“我是字符串”时,您就知道您声明的字符串将保持该值直到时间结束。

          当您不希望方法被扩展您的方法的类覆盖时,应将方法声明为 final。如果这些方法中的任何一个更改了类中的变量,那么只有 final 方法的类仍然可以是可变的。

          我喜欢使用不可修改的类,它确实可以帮助我随时了解程序的状态,并且可以防止难以捕捉的错误。

          【讨论】:

            【解决方案8】:
                class A{
                    public A(){
                        print("A");
                    }
            
                    public void print(String t){
                        System.out.println(t);
                    }
                }
            
                class B extends A{
                    public B(){
                        super();
                    }
            
                    @Override
                    public void print(String t){
                        System.out.println("Not A: " + t);
                    }
                }
            
                new B();
            

            打印“非 A:A”

            如果超类方法“print(”是final的,就不会发生这种类型的错误。

            通过 final,您可以强制执行此方法保持不变,以便 A 始终可以愉快地打印“A”

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2015-12-19
              • 1970-01-01
              • 2013-07-17
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多