笔记之各种内部类实现原理
内部类
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