内部类实现原理

关于内部类的定义和使用,这里不做过多介绍,不太清楚的请先行了解。

自己写了一个类,里面有内部类和局部内部类。通过javac和javap去了解内部类的大体实现过程。


先附上代码

public class Use {
    private String name;

    private Integer age;

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public class UseInner {
        private String innerName;

        public String getInnerName() {
            return innerName;
        }

        public void setInnerName(String innerName) {
            this.innerName = innerName;
        }

        public void testInner() {
            System.out.println("out:" + name + "-" + age + "-" + innerName);
        }
    }

    public String getSendChanenl() {
        class Channel {
            private Integer code;
            private String name;
            private UseInner useInner;

            public Integer getCode() {
                return code;
            }

            public void setCode(Integer code) {
                this.code = code;
            }

            public String getName() {
                return name;
            }

            public void setName(String name) {
                this.name = name;
            }

            public UseInner getUseInner() {
                return useInner;
            }

            public void setUseInner(UseInner useInner) {
                this.useInner = useInner;
            }
        }

        Channel channel = new Channel();
        channel.setCode(1);
        channel.setName("XXX");

        return channel.getCode() + channel.getName() + channel.getUseInner().getInnerName();
    }
}



通过javac Use.java编译后,产生了3个class文件,他们分别是Use.class、Use$1Channel.class和Use$UseInner.class。

分别使用javap命令查看class文件信息。

javap -p Use

Compiled from "Use.java"
public class Use {
  private java.lang.String name;
  private java.lang.Integer age;
  public Use();
  public java.lang.Integer getAge();
  public void setAge(java.lang.Integer);
  public void setName(java.lang.String);
  public java.lang.String getName();
  public java.lang.String getSendChanenl();
  static java.lang.String access$000(Use);
  static java.lang.Integer access$100(Use);
}

上面有两个方法值得我们注意:

static java.lang.String access$000(Use);  为内部类提供外围类name属性的访问

扫描二维码关注公众号,回复: 1566402 查看本文章

static java.lang.Integer access$100(Use); 为内部类提供外围类age属性的访问

默认修饰符加static是当前方法只能在同一个包下访问。而内部类真是通过编译器生成一个同一个包下的类,来实现内部类。


javap -p Use\$1Channel.class

Compiled from "Use.java"
class Use$1Channel {
  private java.lang.Integer code;
  private java.lang.String name;
  private Use$UseInner useInner;
  final Use this$0;
  Use$1Channel(Use);
  public java.lang.Integer getCode();
  public void setCode(java.lang.Integer);
  public java.lang.String getName();
  public void setName(java.lang.String);
  public Use$UseInner getUseInner();
  public void setUseInner(Use$UseInner);
}

这里把Use对象通过构造函数构造进来,就是为了能够访问外围类,且这里是final修饰的,对应唯一。


javap -p Use\$UseInner.class

Compiled from "Use.java"
public class Use$UseInner {
  private java.lang.String innerName;
  final Use this$0;
  public Use$UseInner(Use);
  public java.lang.String getInnerName();
  public void setInnerName(java.lang.String);
  public void testInner();
}

这个和上面的类似,也是把Use构造进来。


如果您有疑问,欢迎留言评论!

猜你喜欢

转载自blog.csdn.net/codingtu/article/details/79336026
今日推荐