匿名內部類常見用法



class
Main { public static void main(String[] args) { for (int i = 0; i < 3; i++) { Thread thread = new Thread(){ @Override public void run(){ for (int i = 0; i < 3; i++) { System.out.print(i+" "); } System.out.println(); } }; System.out.println(thread.getName()); thread.start(); } } }
Thread-0
Thread-1
Thread-2
0 1 2 0 1 2 0 1 2 

Thread匿名內部類

 

 

 

Runnable的匿名內部類

class Main {
    public static void main(String[] args) {
        for (int i = 0; i < 3; i++) {
            Runnable runnable = new Runnable(){
                @Override
                public void run() {
                    for (int i = 0; i < 3; i++) {
                        System.out.print(i+" ");
                    }
                    System.out.println();
                }
            };
            Thread thread = new Thread(runnable);
            System.out.println(thread.getName()+" "+thread.getId());
            thread.start();
        }

    }
}
Thread-0 11
Thread-1 12
Thread-2 13
0 1 2 
0 1 2 
0 1 2 

 

接口匿名內部類

interface icomputer{
    void buyPC();
}
class Demo{
    public static void main(String[] args) {
        icomputer icomputer = new icomputer() {
            @Override
            public void buyPC() {
                System.out.println("買一台MAC");
            }
        };
        icomputer.buyPC();
    }
}
買一台MAC

 

抽象類匿名內部類

abstract  class animals{
    abstract void eat();
}
class People{
    public static void main(String[] args) {
        animals animals = new animals() {
            @Override
            void eat() {
                System.out.println("吃面條");
            }
        };
        animals.eat();
    }
}
吃面條

 

 

為什么要有匿名內部類?

eg:

abstract  class animals{
    abstract void eat();
}
class People extends animals{

    @Override
    void eat() {
        System.out.println("吃面條");
    }
}

class Demo{
    public static void main(String[] args) {
        animals animals = new People();
        animals.eat();
    }
}



class Demo1{
    public static void main(String[] args) {
        animals animals = new animals(){
            @Override
            void  eat(){
                System.out.println("吃面條");
            }
        };
        animals.eat();
    }
}

因為如果抽象類或接口的實現類我們只實現一次,那么重新寫一個實現類會比較麻煩,用來簡化代碼,所以引出了匿名內部類。匿名內部類必須重寫接口或者抽象類中的全部抽象方法,可以調用抽象類中的靜態常量或者抽象類中非private修飾的變量

 

abstract class animals{
  int age = 6;
  private int tall;
    abstract void eat();
    abstract void sleep();
}



class Demo1{

    public static void main(String[] args) {
       animals animal = new animals() {
           @Override
           public void eat() {
               System.out.println("吃面條");
           }

           @Override
           public void sleep() {
               System.out.println("年齡為"+age);
               System.out.println("上床睡覺");
           }
           public void print(){
               System.out.println(age);
           }

       };
        animal.eat();
        animal.sleep();
//        ((animals) animal).print();  該條語句無法被執行,因為抽象類中不含該方法
       
    }
}
吃面條
年齡為6
上床睡覺

 

1、匿名內部類不能定義任何靜態成員、方法。

2、匿名內部類中的方法不能是抽象的;

3、匿名內部類必須實現接口或抽象父類的所有抽象方法。

4、匿名內部類不能定義構造器;

5、匿名內部類訪問的外部類成員變量或成員方法必須用static修飾;

6、內部類可以訪問外部類私有變量和方法。

1、匿名內部類因為沒有類名,可知匿名內部類不能定義構造器

2、因為在創建匿名內部類的時候,會立即創建它的實例,可知匿名內部類不能是抽象類,必須實現接口或抽象父類的所有抽象方法

3、匿名內部類會繼承一個父類(有且只有一個)或實現一個接口(有且只有一個),實現父類或接口中所有抽象方法,可以改寫父類中的方法,添加自定義方法。

5、當匿名內部類和外部類有同名變量(方法)時,默認訪問的是匿名內部類的變量(方法),要訪問外部類的變量(方法)則需要加上外部類的類名。

6、從Outer.class反編譯代碼中可看出自動生成了兩個靜態方法:access$0()和access$1(),並在測試3和測試4中通過Outer類名直接調用,這樣實現了內部類對外部類私有成員變量和方法的訪問。可知內部類可以訪問外部類私有變量和方法


疑問

匿名內部類不能含有static的變量和方法。但是測試發現變量可以被static final修飾,為什么?

主要是因為final類型在編譯期間jvm有優化,常量池會維護這些變量。雖然非靜態內部類不能脫離外部類這個上下文實例化,但是常量池使得final變量脫離了類實例化這個條件,編譯期間便可確定。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM