2

これは私のコードです

package alpha ;

class A1
{
    static class A11
    {
        private
            final // WHAT IS THE EFFECT OF THIS MODIFIER?
            void fun ( String caller )
            {
                System . out . println ( "A11:\t" + caller ) ;
            }
    }

    static class A12 extends A11
    {
        private void fun ( String caller )
        {
            super . fun ( caller + caller ) ;
        }
    }

    public static void main ( String [ ] args )
    {
        A12 a12 = new A12 ( ) ;
        a12 . fun ( "Hello" ) ;
    }
}

A1.A11の最後のmdiferがある場合とない場合で、プログラムがコンパイルされて実行されることがわかりました。

最後の修飾子がないと、A1.A12はfunメソッドを表示してオーバーライドできることを理解できます。プライベートですが、同じクラスに属しているため、視認性の問題はありません。

なぜそれがfinal修飾子で機能するのか理解できません。A1.A12でのオーバーライドを禁止すべきではありませんか?

これは、最終的な修飾子が配置されたプログラムの出力です。

java alpha/A1
A11:    HelloHello

それが単に他の楽しい方法を無視していたなら、

  1. コンパイラはスーパーリファレンスについて文句を言っていなかっただろう
  2. A11は出力に含まれません
4

2 に答える 2

7

メソッドはprivateです。

可視性を保護されたものに変更して、期待される動作を確認します。つまり、メソッドが保護されている場合、パブリックまたはデフォルトの可視性であり、オーバーライドの概念さえ存在します。

このようなことをする -

class A1
{
    static class A11
    {
        public
            final // WHAT IS THE EFFECT OF THIS MODIFIER?
            void fun ( String caller )
            {
                System . out . println ( "A11:\t" + caller ) ;
            }
    }

    static class A12 extends A11
    {
        public void fun ( String caller )
        {
            super . fun ( caller + caller ) ;
        }
    }

    public static void main ( String [ ] args )
    {
        A12 a12 = new A12 ( ) ;
        a12 . fun ( "Hello" ) ;
    }
}

コンパイル時の例外をスローするようになりました

fun(java.lang.String) in A1.A12 cannot override fun(java.lang.String) in A1.A11; overridden method is final
于 2011-07-28T18:07:47.550 に答える
2

publicprotectedおよびパッケージのプライベート/デフォルト アクセス メソッドについては、final実際にメソッドがオーバーライドされるのを防ぎます。

ただし、すべてのprivateメソッドは「非仮想」であるため、実質的に最終的なものです。スーパークラスのprivateメソッドは、派生クラスに違いはありません。オーバーライドしているのではなく、基本クラスのメソッドが無視されるだけです。

JVM のベースとなっている初版の Java 言語仕様には、内部クラスやネストされたクラスがなかったため、privateメソッドを特別に処理することができました。それ以降のバージョンの言語は、JVM を中心に曲げられています。

バイトコード用語では、privateメソッドはinvokespecialではなく で呼び出されinvokevirtualます。

異なるパッケージのデフォルト アクセス/パッケージ プライベートfinalメソッドも、互いに独立しています。同じパッケージ内では、互いにオーバーライドfinalして違いを生むことができます。異なるパッケージでは、一致するメソッドは互いにオーバーライドしません。

于 2011-07-28T18:12:02.957 に答える