美文网首页
java内部匿名类

java内部匿名类

作者: eblly | 来源:发表于2017-03-15 10:03 被阅读0次

    前言:
    java基础的编写类的时候,会觉得很匿名内部类很神秘.普通的java文件会被编译成class,那内部类和匿名内部类呢?它们被会存在在哪个物理位置?
    本文主要针对匿名内部类.

    本文中有ISay和ISay2两个接口,用于测试对比.

    ISay.java

    public interface ISay {
         void sayHello();
     }
    

    ISay2.java

    public interface ISay2 {
         void sayHello222();
    
         void print();
     }
    

    Program.java

    public class Program {
        public static void main(String[] args) {
            ISay say = new ISay() {
                public void sayHello() {
                    System.out.println("Hello java!");
                }
            };
    
            ISay say2 = new ISay() {
                public void sayHello() {
                    System.out.println("Hello java!");
                }
            };
    
            ISay say3 = new ISay() {
                public void sayHello() {
                    System.out.println("Hello java!");
                }
            };
    
    
            ISay2 say2_1 = new ISay2() {
                public void sayHello222() {
                    System.out.println("Hello java!");
                }
    
                public void print(){
                    System.out.print("print");
                }
            };
     
            say.sayHello();
            say2.sayHello();
            say2_1.sayHello222();
            say2_1.print();
        }
    }
    

    生成的class文件如下图:
    ISay.java

    public interface ISay {
         void sayHello();
     }
    

    ISay2.java

    public interface ISay2 {
         void sayHello222();
    
         void print();
     }
    

    Program.java

    public class Program {
        public static void main(String[] args) {
            ISay say = new ISay() {
                public void sayHello() {
                    System.out.println("Hello java!");
                }
            };
    
            ISay say2 = new ISay() {
                public void sayHello() {
                    System.out.println("Hello java!");
                }
            };
    
            ISay say3 = new ISay() {
                public void sayHello() {
                    System.out.println("Hello java!");
                }
            };
    
    
            ISay2 say2_1 = new ISay2() {
                public void sayHello222() {
                    System.out.println("Hello java!");
                }
    
                public void print(){
                    System.out.print("print");
                }
            };
     
            say.sayHello();
            say2.sayHello();
            say2_1.sayHello222();
            say2_1.print();
        }
    }
    

    生成的class文件如下图:


    6863841.png

    发现会有Program$1.class等文件,其实这就是匿名类的class文件.

    使用jclasslib查看Program.class字节码
    ###是注释,不是字节码的内容

    new #2 <NewInterface/Program$1>                      ###对应代码ISay say = new Program$1() ,Program$1是ISay的实现。
    dup                                                                                                                                                                                                       
    invokespecial #3 <NewInterface/Program$1.<init>>
    astore_1                                             ###存放引用在变量1中
    
    new #4 <NewInterface/Program$2>
    dup
    invokespecial #5 <NewInterface/Program$2.<init>>
    astore_2
    
    new #6 <NewInterface/Program$3>
    dup
    invokespecial #7 <NewInterface/Program$3.<init>>
    astore_3
    
    new #8 <NewInterface/Program$4>
    dup
    invokespecial #9 <NewInterface/Program$4.<init>>
    astore 4
    
    aload_1                                                      ###加载本地变量1的引用,即上述的NewInterface/Program$1
    invokeinterface #10 <NewInterface/ISay.sayHello> count 1     ###调用方法,对象是本地变量1的实例。
    
    aload_2
    invokeinterface #10 <NewInterface/ISay.sayHello> count 1
    
    aload 4                                                      ###加载本地变量4的引用,即上述的NewInterface/Program$4
    invokeinterface #11 <NewInterface/ISay2.sayHello222> count 1 ###调用方法,对象是本地变量4的实例。
    
    aload 4
    invokeinterface #12 <NewInterface/ISay2.print> count 1
    return
    

    内部类跟匿名内部类的class生成规则差不多,只不过匿名内部类是由编译器命令,内部类是直接指定.
    例如:Program中有一个内部类叫Book,那么生成的class文件是Program$Book.class

    相关文章

      网友评论

          本文标题:java内部匿名类

          本文链接:https://www.haomeiwen.com/subject/kuflnttx.html