ホームページ Java &#&チュートリアル 匿名内部クラスの詳細な説明

匿名内部クラスの詳細な説明

Dec 15, 2016 pm 12:29 PM
匿名内部クラス

Javaの改善編 - 内部クラスの詳細説明では、匿名内部クラスについて簡単に紹介していますが、内部クラスには他にも細かい問題がまだたくさんあるため、このブログが派生しました。このブログでは、匿名内部クラスの使用法、匿名内部クラスで注意すべきこと、匿名内部クラスを初期化する方法、および匿名内部クラスで使用される仮パラメータが Final でなければならない理由について学ぶことができます。


1. 匿名内部クラスを使用する 内部クラス

匿名内部クラスには名前がないため、作成方法が少し奇妙です。作成形式は次のとおりです:

new 父类构造器(参数列表)|实现接口()    
    {    
     //匿名内部类的类体部分    
    }
ログイン後にコピー

ここで、匿名内部クラスを使用するには、親クラスを継承するか、インターフェイスを実装する必要があることがわかります。 もちろん、親クラスを継承するか、インターフェイスを実装できるのは 1 つだけです。同時に、匿名内部クラスは new を直接使用してオブジェクトへの参照を生成するため、class キーワードがありません。もちろん、この参照は暗黙的です。

public abstract class Bird {  
    private String name;  
  
    public String getName() {  
        return name;  
    }  
  
    public void setName(String name) {  
        this.name = name;  
    }  
      
    public abstract int fly();  
}  
  
public class Test {  
      
    public void test(Bird bird){  
        System.out.println(bird.getName() + "能够飞 " + bird.fly() + "米");  
    }  
      
    public static void main(String[] args) {  
        Test test = new Test();  
        test.test(new Bird() {  
              
            public int fly() {  
                return 10000;  
            }  
              
            public String getName() {  
                return "大雁";  
            }  
        });  
    }  
}  
------------------  
Output:  
大雁能够飞 10000米
ログイン後にコピー

Test クラスでは、test() メソッドは Bird 型パラメータを受け入れますが、同時に、抽象クラスを直接新規作成する方法がないこともわかっています。その前に、まず実装クラスを作成する必要があります。実装クラスのインスタンス。したがって、メイン メソッドで匿名内部クラスを直接使用して、Bird インスタンスを作成します。

匿名内部クラスは抽象クラスになることができないため、その抽象親クラスまたはインターフェイスにすべての抽象メソッドを実装する必要があります。名前 この匿名内部コードは、実際には次の形式に分割できます:

public class WildGoose extends Bird{  
    public int fly() {  
        return 10000;  
    }  
      
    public String getName() {  
        return "大雁";  
    }  
}  
  
WildGoose wildGoose = new WildGoose();  
test.test(wildGoose);
ログイン後にコピー

ここで、システムは Bird クラスから匿名クラスを継承するオブジェクトを作成し、それが Bird 型への参照に変換されます。

匿名内部クラスの使用には欠陥があります。つまり、匿名内部クラスを作成すると、すぐにクラスのインスタンスが作成され、クラスの定義がすぐに消えてしまいます。 , そのため、匿名内部クラスを再利用することはできません。上記の例では、test() メソッドで内部クラスを複数回使用する必要がある場合は、匿名内部クラスを使用する代わりにクラスを再定義することをお勧めします。


2. 注意事項

匿名内部クラスを使用する際には、以下の点に注意する必要があります。

1. 匿名内部クラスを使用する場合、クラスを継承したり、インターフェースを実装したりする必要がありますが、両方 両方を持つことはできず、1 つのクラスを継承するか、1 つのインターフェイスのみを実装できます。

2. 匿名内部クラスではコンストラクターを定義できません。

3. 匿名内部クラスには静的メンバー変数と静的メソッドを含めることはできません。

4. 匿名内部クラスはローカル内部クラスであるため、ローカル内部クラスに対するすべての制限は匿名内部クラスにも適用されます。

5. 匿名内部クラスは、継承されたクラスまたは実装されたインターフェイスのすべての抽象メソッドを実装する必要があります。


3. 使用する仮パラメータをfinalにする必要があるのはなぜですか

匿名の内部クラスにパラメータを渡すとき、内部クラスで仮パラメータを使用する必要がある場合、仮パラメータはfinalでなければなりません。つまり、メソッドの仮パラメータを内部クラスで使用する必要がある場合、仮パラメータはfinalでなければなりません。

なぜ最終的なものでなければならないのですか?

まず、内部クラスが正常にコンパイルされた後、クラス ファイルが生成されることがわかります。このクラス ファイルは外部クラスと同じクラス ファイルではなく、外部クラスへの参照のみを保持します。外部クラスによって渡されたパラメータを内部クラスによって呼び出す必要がある場合、Java プログラムの観点からは、それらは直接呼び出されます:

public class OuterClass {  
    public void display(final String name,String age){  
        class InnerClass{  
            void display(){  
                System.out.println(name);  
            }  
        }  
    }  
}
ログイン後にコピー

上記のコードから、name パラメータは次のように直接呼び出される必要があるように見えます。内部クラス?実際にはそうではありません。Java コンパイル後の実際の動作は次のとおりです:

public class OuterClass$InnerClass {  
    public InnerClass(String name,String age){  
        this.InnerClass$name = name;  
        this.InnerClass$age = age;  
    }  
      
      
    public void display(){  
        System.out.println(this.InnerClass$name + "----" + this.InnerClass$age );  
    }  
}
ログイン後にコピー

したがって、上記のコードから判断すると、内部クラスはメソッドによって渡されたパラメーターを直接呼び出すのではなく、独自のコンストラクターを使用してバックします。メソッドが実際に呼び出すのは、外部メソッドによって渡されたパラメーターではなく、メソッド自体のプロパティです。

直到这里还没有解释为什么是final?在内部类中的属性和外部方法的参数两者从外表上看是同一个东西,但实际上却不是,所以他们两者是可以任意变化的,也就是说在内部类中我对属性的改变并不会影响到外部的形参,而然这从程序员的角度来看这是不可行的,毕竟站在程序的角度来看这两个根本就是同一个,如果内部类该变了,而外部方法的形参却没有改变这是难以理解和不可接受的,所以为了保持参数的一致性,就规定使用final来避免形参的不改变。

简单理解就是,拷贝引用,为了避免引用值发生改变,例如被外部类的方法修改等,而导致内部类得到的值不一致,于是用final来让该引用不可改变。

故如果定义了一个匿名内部类,并且希望它使用一个其外部定义的参数,那么编译器会要求该参数引用是final的。


四、匿名内部类初始化

我们一般都是利用构造器来完成某个实例的初始化工作的,但是匿名内部类是没有构造器的!那怎么来初始化匿名内部类呢?使用构造代码块!利用构造代码块能够达到为匿名内部类创建一个构造器的效果。

public class OutClass {  
    public InnerClass getInnerClass(final int age,final String name){  
        return new InnerClass() {  
            int age_ ;  
            String name_;  
            //构造代码块完成初始化工作  
            {  
                if(0 < age && age < 200){  
                    age_ = age;  
                    name_ = name;  
                }  
            }  
            public String getName() {  
                return name_;  
            }  
              
            public int getAge() {  
                return age_;  
            }  
        };  
    }  
      
    public static void main(String[] args) {  
        OutClass out = new OutClass();  
          
        InnerClass inner_1 = out.getInnerClass(201, "chenssy");  
        System.out.println(inner_1.getName());  
          
        InnerClass inner_2 = out.getInnerClass(23, "chenssy");  
        System.out.println(inner_2.getName());  
    }  
}
ログイン後にコピー


更多详解匿名内部类相关文章请关注PHP中文网!

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Java の匿名内部クラスはメモリ リークの問題をどのように解決しますか? Java の匿名内部クラスはメモリ リークの問題をどのように解決しますか? May 01, 2024 pm 10:30 PM

匿名の内部クラスはメモリ リークを引き起こす可能性があります。問題は、匿名の内部クラスが外部クラスへの参照を保持し、外部クラスのガベージ コレクションが妨げられることです。解決策には次のものが含まれます。 1. 弱参照を使用します。外部クラスが強参照によって保持されなくなった場合、ガベージ コレクターは弱い参照オブジェクトをすぐにリサイクルします。ガベージ コレクション中にメモリが必要になるため、ソフト参照オブジェクトがリサイクルされます。 Android アプリケーションなどの実戦では、匿名内部クラスによるメモリ リークの問題は、弱参照を使用することで解決でき、リスナーが不要な場合には匿名内部クラスを再利用できます。

Java の匿名内部クラスの設計パターンは何ですか? Java の匿名内部クラスの設計パターンは何ですか? May 02, 2024 pm 04:42 PM

匿名内部クラスは、明示的な名前を持たず、new 式を通じて作成される Java の特別な内部クラスであり、主に特定のインターフェイスの実装または抽象クラスの拡張に使用され、作成直後に使用されます。一般的な匿名内部クラスの設計パターンには次のものがあります。 アダプター パターン: 1 つのインターフェイスを別のインターフェイスに変換します。戦略パターン: アルゴリズムの定義と置換。オブザーバー パターン: オブザーバーを登録し、イベントを処理します。これは、文字列の長さによる TreeSet の並べ替え、匿名スレッドの作成など、実際のアプリケーションで非常に役立ちます。

Java の匿名内部クラスの利点は何ですか? Java の匿名内部クラスの利点は何ですか? Apr 30, 2024 am 11:39 AM

匿名内部クラスは、サブクラス化、コードの簡素化、およびイベント (ボタンのクリックなど) の処理を​​容易にする特別な内部クラスとして Java で使用されます。実際のケースは次のとおりです。 イベント処理: 匿名の内部クラスを使用して、ボタンのクリック イベント リスナーを追加します。データ変換: Collections.sort メソッドと匿名内部クラスをコンパレータとして使用してコレクションを並べ替えます。

Java の匿名内部クラスでよくある間違いは何ですか? Java の匿名内部クラスでよくある間違いは何ですか? May 02, 2024 am 09:03 AM

匿名内部クラスの使用エラー: 非スレッドセーフ環境で未宣言の例外をキャッチすることを使用してスコープ外の変数にアクセスする

Java 匿名内部クラスのパフォーマンスを最適化するにはどうすればよいですか? Java 匿名内部クラスのパフォーマンスを最適化するにはどうすればよいですか? May 02, 2024 am 08:48 AM

匿名内部クラスのパフォーマンスの問題は、それらが使用されるたびに再作成されることです。これは、次の戦略によって最適化できます。 1. 匿名内部クラスをローカル変数に格納する。 2. 非静的内部クラスを使用する。 3. ラムダを使用する。表現。実際のテストでは、ラムダ式の最適化が最も効果的であることが示されています。

Java 匿名内部クラスのライフサイクルは何ですか? Java 匿名内部クラスのライフサイクルは何ですか? May 01, 2024 pm 04:06 PM

匿名内部クラスの有効期間は、そのスコープによって決まります。 メソッドローカル内部クラス: それを作成したメソッドのスコープ内でのみ有効です。コンストラクターの内部クラス: 外部クラスのインスタンスにバインドされ、外部クラスのインスタンスが解放されると解放されます。静的内部クラス: 外部クラスと同時にロードおよびアンロードされます。

Java 匿名内部クラスが使用に適さないのはどのようなシナリオですか? Java 匿名内部クラスが使用に適さないのはどのようなシナリオですか? May 03, 2024 pm 05:42 PM

匿名内部クラスは、プライベート メンバーにアクセスする必要がある、複数のインスタンスが必要な、継承が必要な、ジェネリック型にアクセスする必要がある場合の使用には適していません。

Java の匿名内部クラスはスレッドにどのように適用されますか? Java の匿名内部クラスはスレッドにどのように適用されますか? May 02, 2024 pm 01:57 PM

匿名の内部クラスにより、マルチスレッド コードの作成が簡素化され、名前を付ける必要がなくなり、スレッド クラスの即時定義と使用が可能になります。主な利点はコードを簡素化できることですが、コードを拡張できないという制限があります。 1 つまたは 2 つのスレッドをすばやく作成する必要がある場合に使用します。より複雑なロジックが必要な場合は、別のクラス ファイルを作成する必要があります。

See all articles