笔记之各种内部类实现原理

内部类

1.静态内部类

public class Outer{
    private static int shared = 100;
    public static class StaticInner {
        public void innerMethod(){
            System.out.println("innered " + shared);
        }
    }
    public void test(){
        StaticInner si = new StaticInner();
        si.innerMethod();
    }
}

// 静态内部类可以被外部调用
Outer.StaticInner si = new Outer.StaticInner();
si.innerMethod();

实现为

public class Outer {
    private static int shared = 100;
    public void test(){
        Outer$StaticInner si = new Outer$StaticInner();
        si.innerMethod();
    }
    static int access$0(){
        return shared;
    }
}
public class Outer$StaticInner{
    public void innerMethod() {
        System.out.println("inner " + Outer.access$0());
    }
}

2.成员内部类

public class Outer {
    private int a = 100;
    public class Inner {
        public void innerMethos(){
            System.out.println("Outer a " + a);
            Outer.this.action();
        }
    }
    private void action(){
        System.out.println("action");
    }
    public void test(){
        Inner inner = new Inner();
        inner.innerMethod();
    }
}
//成员内部类可以通过  外部类.this.xxx 的方式来引用外部类的实例变量和方法,
//比如Outer.this.action()

//外部使用的时候需要先创建外部类对象,再通过外部类对象来创建内部类对象
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
inner.innerMethod();

实现

public class Outer {
    private int a = 100;
    private void action(){
        System.out.prinln("action");
    }
    public void test(){
        Outer$Inner inner = new Outer$Inner(this);
        inner.innerMethod();
    }
    static int access$0(Outer outer){
        return outer.a;
    }
    static void access$1(Outer outer){
        outer.action();
    } 
}

public class Outer$Inner{
    final Outer outer;
    public Outer$Inner(Outer outer){
        this.outer = outer;
    }
    public void innerMethod() {
        System.out.println("outer a " + Outer.access$0(outer));
    }
}

//自动生成静态方法,通过传递一个对象参数来获取对象的实例变量方法

3.方法内部类

public class Outer{
    private int a = 100;
    public void test(final int param){
        final String str = "hello";
        class Inner {
            public void  innerMethod(){
                System.out.println("Outer a " + a);
                System.out.println("param " + param);
                System.out.println("local var " + str);
            }
        }
        Inner inner = new Inner();
        inner.innerMethod();
    }
}

实现

public class Outer {
    private int a = 100;
    public void test(final int param){
        final String str = "hello";
        OutenInner inner = new OuterInner(this, param);
        inner.innerMethod();
    }
    static int access$0(Outer outer){
        return outer.a;
    }
}
public class OuterInner {
    Outer outer;
    int param;
    OuterInner(Outer outer, int param){
        this.outer = outer;
        this.param = param;
    }
    public void innerMethod(){
        System.out.println("outer a" + outer.access$0(this.outer));
        System.out.println("param " + param);
        System.out.println("loacl var " + "hello");
    }
}

//这里方法的参数,以及局部变量是通过复制值到实际的内部类对象中去的,因此若在内部对象中改变局部变量或是方法参数,并不能反映到外部,故应该将这些值声明为final。
//若的确有需要改动的地方,可以将这些局部变量或者参数放在数组中,数组声明为final

4.匿名内部类

public class Outer{
    public void test(final int x, final int y){
        Point p = new Point(2,3){
            @Override
            public double distance(){
                return distance(new Point(x,y));
            }
        }
        System.out.println(p.distance());
    }
}

实现

public class Outer {
    public void test(final int x, final int y){
        Point p = new Outer$1(this,2,3,x,y);
        System.out.println(p.distance());
    }
}
public class Outer$1 extends Point{
    int x2;
    int y2;
    Outer outer;
    Outer$1(Outer outer, int x1, int y1, int x2, int y2){
        super(x1, y1);
        this.outer = outer;
        this.x2 = x2;
        this.y2 = y2;
    }
    @Override
    public double distance(){
        return distance(new Point(this.x2, this.y2));
    }
}
//生成一个匿名内部类父类为Point,方法参数和局部变量也需要声明为final

猜你喜欢

转载自www.cnblogs.com/pcmpcm/p/12284038.html