搜尋
首頁Javajava教程詳解匿名內部類
詳解匿名內部類Dec 15, 2016 pm 12:29 PM
匿名內部類別

      在Java提高篇-----詳解內部類別中對匿名內部類別做了一個簡單的介紹,但是內部類別還存在很多其他細節問題,所以就衍生出這篇部落格。在這篇部落格中你可以了解到匿名內部類別的使用、匿名內部類別要注意的事項、如何初始化匿名內部類別、匿名內部類別使用的形參為何要為final。


       一、使用匿名內部類內部類

        建立格式如下:

new 父类构造器(参数列表)|实现接口()    
    {    
     //匿名内部类的类体部分    
    }

       在這裡我們看到使用匿名內部類別我們必須要繼承一個父類別或實作一個接口,當然也只能只繼承一個父類別或實作一個介面。同時它也是沒有class關鍵字,這是因為匿名內部類別是直接使用new來產生一個物件的參考。當然這個引用是隱性的。

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型別的參數,同時我們知道一個抽象類別是沒有辦法直接new的,我們必須先有實作類別才能new出來它的實作類別實例。所以在mian方法中直接使用匿名內部類別來建立一個Bird實例。

       由於匿名內部類別不能是抽象類別,所以它必須實現它的抽象父類別或介面裡面所有的抽象方法。

     收到

       對於匿名內部類別的使用它是存在一個缺陷的,就是它只能被使用一次,創建匿名內部類別時它會立即創建一個該類別的實例,該類別的定義會立即消失,所以匿名內部類別是不能夠被重複使用。對於上面的實例,如果我們需要對test()方法裡面內部類別進行多次使用,建議重新定義類別,而不是使用匿名內部類別。


       二、注意事項

       在使用匿名內部類別的過程中,因此我們需要注意如同一個點:

?者不可兼得,同時也只能繼承一個類別或實作一個介面。

      2、匿名內部類別中是無法定義建構子的。

      3、匿名內部類別中不能有任何的靜態成員變數與靜態方法。

      4、匿名內部類別為局部內部類別,所以局部內部類別的所有限制同樣對匿名內部類別生效。

      5、匿名內部類別不能是抽象的,它必須實現繼承的類別或所有實現的介面的抽象方法。

       三、使用的形參為何要為final

       我們給予匿名類傳遞參數的時候,且該形參在內部類別中若要使用,那麼內部類別若為匿名類別。也就是說:當所在的方法的形參需要被內部類別裡面使用時,該形參必須為final。

      為什麼必須為final呢?

      首先我們知道在內部類別編譯成功後,它會產生一個class文件,該class文件與外部類別並不是同一class文件,僅僅只保留對外部類別的引用。當外部類別傳入的參數需要被內部類別呼叫時,從java程式的角度來看是直接被呼叫:

public class WildGoose extends Bird{  
    public int fly() {  
        return 10000;  
    }  
      
    public String getName() {  
        return "大雁";  
    }  
}  
  
WildGoose wildGoose = new WildGoose();  
test.test(wildGoose);

從上面程式碼看好像name參數應該是被內部類別直接呼叫?其實不然,在java編譯之後實際的操作如下:

public class OuterClass {  
    public void display(final String name,String age){  
        class InnerClass{  
            void display(){  
                System.out.println(name);  
            }  
        }  
    }  
}

       所以從上面程式碼來看,內部類別並不是直接呼叫方法傳遞的參數,而是利用自身的構造器對傳入的參數進行備份,自己內部方法呼叫的實際上時自己的屬性而不是外部方法傳遞進來的參數。

       直到这里还没有解释为什么是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
Java 匿名内部类如何解决内存泄漏问题?Java 匿名内部类如何解决内存泄漏问题?May 01, 2024 pm 10:30 PM

匿名内部类可导致内存泄漏,问题在于它们持有外部类的引用,从而阻止外部类被垃圾回收。解决方法包括:1.使用弱引用,当外部类不再被强引用持有时,垃圾回收器会立即回收弱引用对象;2.使用软引用,垃圾回收器会在进行垃圾回收时需要内存时才回收软引用对象。在实战中,例如Android应用中,可以通过使用弱引用来解决因匿名内部类引起的内存泄漏问题,从而在不需要监听器时回收匿名内部类。

Java 匿名内部类的设计模式有哪些?Java 匿名内部类的设计模式有哪些?May 02, 2024 pm 04:42 PM

匿名内部类是Java中没有显式名称、通过new表达式创建的特殊内部类,主要用于实现特定接口或扩展抽象类,并在创建后立即使用。常见的匿名内部类设计模式包括:适配器模式:将一个接口转换为另一个接口。策略模式:定义和替换算法。观察者模式:注册观察者并处理事件。它在实际应用中非常有用,例如按字符串长度排序TreeSet、创建匿名线程等。

Java 匿名内部类有哪些优势?Java 匿名内部类有哪些优势?Apr 30, 2024 am 11:39 AM

匿名内部类在Java中作为方便创建子类、简化代码和处理事件(例如按钮单击)的特殊内部类。实战案例包括:事件处理:使用匿名内部类为按钮添加单击事件监听器。数据转换:使用Collections.sort方法和匿名内部类作为比较器对集合进行排序。

Java 匿名内部类的生命周期是怎样的?Java 匿名内部类的生命周期是怎样的?May 01, 2024 pm 04:06 PM

匿名内部类的生命周期由其作用域决定:方法局部内部类:仅在创建它的方法范围内有效。构造器内部类:与外部类实例绑定,当外部类实例释放时释放。静态内部类:与外部类同时加载卸载。

Java 匿名内部类有哪些常见错误?Java 匿名内部类有哪些常见错误?May 02, 2024 am 09:03 AM

匿名内部类使用错误:在非线程安全环境中使用捕获未声明的异常访问超出范围的变量

Java 匿名内部类如何优化性能?Java 匿名内部类如何优化性能?May 02, 2024 am 08:48 AM

匿名内部类的性能问题在于每次使用都会重新创建,可通过以下策略优化:1.将匿名内部类存储在局部变量中;2.使用非静态内部类;3.使用lambda表达式。实战测试表明lambda表达式优化效果最佳。

Java 匿名内部类的替代方案是什么?Java 匿名内部类的替代方案是什么?Apr 30, 2024 pm 01:15 PM

Lambda表达式作为匿名内部类的替代方案,提供了更简洁的方式来定义函数式接口的实现:使用简短语法(parameters)->expression定义匿名函数。适用于需要实现函数式接口(只有一个抽象方法)的场合。能够简化列表排序和线程定义等任务。

Java 匿名内部类如何应用于线程?Java 匿名内部类如何应用于线程?May 02, 2024 pm 01:57 PM

匿名内部类可简化多线程代码的创建,无需命名,支持即时定义和使用线程类。主要优势在于简化代码,而限制是无法扩展。在需要快速创建一两个线程时使用,保持代码简短,如果需要更复杂的逻辑,应创建单独的类文件。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前By尊渡假赌尊渡假赌尊渡假赌
倉庫:如何復興隊友
1 個月前By尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具