A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 暗影流光 中级黑马   /  2014-7-10 11:05  /  3235 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

1、非静态内部类什么时候加载到内存中?加载到内存中的哪个内存区域?
2、静态内部类什么时候加载到内存中?加载到内存中的哪个内存区域?

5 个回复

倒序浏览
还是要看时机吧,非静态内部类在外部类里面和平时使用的其他类没有什么区别,当外部类需要创建静态内部类对象的时候自然就调用非静态内部类的的构造方法来创建内存空间了。至于加载到内存的哪个区域,我想应该还是堆内存空间吧,栈内存空间保留一个构造方法返回的引用。静态内部类因为加入了static修饰则说明它的生存期是与它的外部类的生存期是相同的。也就是说什么时候外部类被创建加载进内存,静态内部类也一定加载进内存了。个人的想法,欢迎指正。
回复 使用道具 举报
mytongyong 发表于 2014-7-10 11:27
还是要看时机吧,非静态内部类在外部类里面和平时使用的其他类没有什么区别,当外部类需要创建静态内部类对 ...

当创建一个外部类对象的时候,首先外部类的字节码文件会先加载进方法区中,然后在堆内存中创建一个对象。那么这个时候,内部类的字节码文件也会跟着加载进方法区中吗?
回复 使用道具 举报
非静态内部类,在对象建立的时候加载到内存中的,加载到栈中,
回复 使用道具 举报
静态内部类,实在对象建立前就加载到内存中的,加载到堆
回复 使用道具 举报
暗影流光 发表于 2014-7-10 11:34
当创建一个外部类对象的时候,首先外部类的字节码文件会先加载进方法区中,然后在堆内存中创建一个对象。 ...
  1. public class Cow {
  2.         private double weight;

  3.         // 外部类的两个重载的构造器
  4.         public Cow() {
  5.         }

  6.         public Cow(double weight) {
  7.                 this.weight = weight;
  8.         }

  9.         // 定义一个非静态内部类
  10.         private class CowLeg {
  11.                 // 非静态内部类的连个Field
  12.                 private double length;
  13.                 private String color;

  14.                 // 非静态内部类的两个重载的构造器
  15.                 public CowLeg() {
  16.                 }

  17.                 public CowLeg(double length, String color) {
  18.                         this.length = length;
  19.                         this.color = color;
  20.                 }

  21.                 public void setLength(double length) {
  22.                         this.length = length;
  23.                 }

  24.                 public double getLength() {
  25.                         return this.length;
  26.                 }

  27.                 public void setColor(String color) {
  28.                         this.color = color;
  29.                 }

  30.                 public String getColor() {
  31.                         return this.color;
  32.                 }

  33.                 public void info() {
  34.                         System.out.println("当前牛腿颜色是:" + color + " 高" + length);
  35.                         // 直接访问外部类的private修饰的Field
  36.                         System.out.println("本牛腿所在奶牛重:" + weight);
  37.                 }
  38.         }

  39.         public void test() {
  40.                 CowLeg cl = new CowLeg(1.12, "黑白相间");
  41.         }

  42.         public static void main(String[] args) {
  43.                 Cow cow = new Cow(378.9);
  44.                 cow.test();
  45.         }
  46. }
复制代码
看这段代码执行时的内存分布图:这是我从一本资料上面截图下来的
CowLeg这个内部类是在test()方法内部被初始化,如果我们把Cow.test()注释掉,即java编译器不会为test()方法来单独开辟一个栈区来保存指向test()的引用,换句话说就是test()方法体里面的代码都没有执行,那何来CowLeg的对象呢?当一个对象被创建的时候,与这个对象相关的仅仅是Field(就是构造方法前的初始化块),和构造方法体里面的代码会在堆内存中得到一份拷贝,同时构造方法返回指向这个对象的引用。而与这个类相关的方法,是不会与对象一起被初始化的,除非你把CowLeg这个类的对象的创建放在了构造方法或者说是Field里面,那么毫无疑问,CowLeg的对象肯定会随着Cow类对象的创建而创建。不知道我这么说你有没有理解,我不保证我理解的就是对的。。。但是一起思考吧。。。



回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马