【Java 内部类、匿名内部类、静态内部类的分析】

本文详细介绍了Java中的内部类,包括成员内部类、静态内部类和匿名内部类。成员内部类可以直接访问外部类的所有成员,静态内部类不持有外部类对象,匿名内部类用于简洁地实现继承或接口。同时,文章通过示例分析了编译后的class文件,展示了内部类与外部类之间的关联。
  • 成员内部类

    public class Test {
         //不对外开放的
         class memberInnerClass{
             public void memberInner(){
                 System.out.println("成员内部类");
             }
         }
        //内部类 对外开放
        public  class  inner{
            public  String  innername;
            public void log(){
                System.out.println(" inner log");
            }
        }
    
    }
    
    • 内部类就像一个实例成员一样存在于外部类中。
    • 内部类可以访问外部类的所有成员就想访问自己的成员一样没有限制。
    • 内部类中的this指的是内部类的实例对象本身,如果要用外部类的实例对象就可以用类名.this的方式获得。
    • 内部类对象中不能有静态成员,原因很简单,内部类的实例对象是外部类实例对象的一个成员。
  • 方法内部类

     public class A {
     
         public void A(){
             System.out.println("方法内部类");
         }
     }
    
     public class Test {
         
         public void methodInner(){
             //短暂性的
             class B extends A{
                 
             }
             new B().A();
    
         }
    
    1. 方法中的内部类没有访问修饰符, 即方法内部类对包围它的方法之外的任何东西都不可见。
    2. 方法内部类只能够访问该方法中的局部变量,所以也叫局部内部类。而且这些局部变量一定要是final修饰的常量。
  • 静态内部类

    静态内部类不持有外部类的对象,可以将其完全从外部类中移除,而不会影响。

 //静态内部类
    public static class staticinner{
        public  String  staticinnername;
        public void log(){
            System.out.println("static inner log");
        }
    }
  1. 只能访问外部类的静态成员对象和方法
  2. 不会引起内存泄漏
  • 匿名内部类
  1. 一个类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的事先或是覆盖。
  2. 只是为了获得一个对象实例,不需要知道其实际类型。
  3. 类名没有意义,也就是不需要使用到。
//匿名内部类
    public inner niinner = new inner(){
        public void log(){
            System.out.println("niming inner log");
        }
    };
 //静态匿名内部类,实际上就是匿名内部类,加静态是因为new 的这个类是静态内部类
    public staticinner staticinnerni = new staticinner(){
        public void log(){
            System.out.println("niming static inner log");
        }
    };
  • 命令javac生成的class文件分析

javac javafilename

会对内部类、静态内部类生成相对应的class文件,会对匿名内部类生成$1、$2、$3这样的文件。

DemoOutter.java文件编译后会生成如下的文件:
在这里插入图片描述

可以看到内部类生成inner.class,静态内部类生成staticinner.class文件,而其他的匿名内部类生成$1、$2、$3、$4文件。

//DemoOutter.java
import java.util.ArrayList;
import java.util.Iterator;

public class DemoOutter {

    //内部类
    public  class  inner{
        public  String  innername;
        public void log(){
            System.out.println(" inner log");
        }
    }


    //匿名内部类
    public inner niinner = new inner(){
        public void log(){
            System.out.println("niming inner log");
        }
    };


    //静态内部类
    public static class staticinner{
        public  String  staticinnername;
        public void log(){
            System.out.println("static inner log");
        }
    }


    //静态匿名内部类
    public staticinner staticinnerni = new staticinner(){
        public void log(){
            System.out.println("niming static inner log");
        }
    };
//
//    public staticinner Staticinnerni2 = new staticinner();


    public Runnable mRunable = new Runnable() {
        @Override
        public void run() {
            System.out.println("workThead outter log");
        }
    };

    public void  outterlog(){
        System.out.println("outter log");
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("workThead outter log");
            }
        }).start();
    }


    public static void main(String[] args) {
    }
}

.inner.class 可以看到其多了一个构造函数,该构造函数将外部类的引用给了内部类this.this$0

public class DemoOutter$inner {
    public String innername;

    public DemoOutter$inner(DemoOutter var1) {
        this.this$0 = var1;
    }

    public void log() {
        System.out.println(" inner log");
    }
}

.staticinner.class则没有这个构造函数,不会持有外部类引用

public class DemoOutter$staticinner {
    public String staticinnername;

    public DemoOutter$staticinner() {
    }

    public void log() {
        System.out.println("static inner log");
    }
}

而匿名内部类$1.class和内部类一样持有了外部类的引用。

class DemoOutter$1 extends inner {
    DemoOutter$1(DemoOutter var1) {
        super(var1);
        this.this$0 = var1;
    }

    public void log() {
        System.out.println("niming inner log");
    }
}
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值