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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 芦青 中级黑马   /  2013-4-1 21:20  /  2184 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 芦青 于 2013-4-2 13:29 编辑

想请教一下,如果一个类没有对象,只用类名调用 ..但类中有非静态方法 ,我想知道加载类的时候,非静态方法会被加载吗? 还是一定要创建对象的时候非静态方法才会被加载? 研究一天内存了,越研究越迷茫..

评分

参与人数 1技术分 +1 收起 理由
张熙韬 + 1

查看全部评分

6 个回复

倒序浏览
不会 静态的才会随着类一起加载  非静态的只有创建对象的时候才会被对象加载

回复 使用道具 举报
      静态是随着类的加载而加载的,类加载时,检测有检测静态代码块,静态方法,静态属性等等,若有就统统加载,而且这些静态成员也会随着类的消亡而消亡,说明静态成员的生存周期会很长,比较占资源,这也是静态的弊处之一;
      而非静态成员是对象成员,这个特点就是随着对象的创建而存在,没有对象时,这些非静态成员就不存在,而且非静态成员随着对象的消亡而消亡,从时间上看,非静态出现的比静态要晚;
     根据上述描述,就会很好的了解,静态不能访问非静态了;
      给你一个示例图,可以说明一切,这个假设有一个Person类,主函数执行到Person p=new Person();时,对象建立的过程:

这个看清楚了,就好办了,基本上可以说明内存的动态,希望对你有帮助;

评分

参与人数 1技术分 +1 收起 理由
张熙韬 + 1

查看全部评分

回复 使用道具 举报
邵震 发表于 2013-4-1 21:27
不会 静态的才会随着类一起加载  非静态的只有创建对象的时候才会被对象加载

...

哥们,如果我在主函数中,用类名调用静态成员,这时候会加载类吧..那下面我在创建个该类的对象,难道还要重新加载一次该类去给非静态方法分配内存?
回复 使用道具 举报
不加载类  只调用静态成员    你创建类的成员才加载类中的非静态成员
回复 使用道具 举报
你再创建个对象,也不会加载类,只会加载类中的非静态方法,在栈内存分配空间。
回复 使用道具 举报
我拿一个代码给你当例子讲解吧

  1. public class TestStatic {

  2.         /**
  3.          * main方法执行前会有很多事可干
  4.          */
  5.         //静态代码块会随着.class字节码文件加载入内存而加载,所以静态代码块执行一次
  6.         //静态代码块和静态属性谁先执行,取决于谁在程序代码的上面
  7.         //执行静态属性这行代码创建对象,调用构造方法,必须先加载对象的字节码文件,程序执行到36行
  8.         static AllPerson p1 = new AllPerson();
  9.         static {
  10.                 //静态代码块执行完后,执行main()函数
  11.                 System.out.println("TestStatic静态代码块执行");
  12.         }
  13.         public static void main(String[] args) {
  14.                
  15.                 System.out.println("main函数现在才开始得到执行");
  16.         }

  17. }

  18. class AllAnimal {
  19.         static {
  20.                 //执行下面这行代码后,代表该类字节码文件已经加载进内存了,然后再加载子类字节码文件,又重新跳回33行
  21.                 System.out.println("AllAnimal静态代码块执行");
  22.         }
  23.         //父类构造方法执行完成后,子类中的静态属性加载完毕,调用子类的构造方法,子类的构造方法又会调用父类的工作方法
  24.         //所以会出现AllAnimal构造方法执行连续出现两行的情况,程序跳到46行
  25.         public AllAnimal() {
  26.                 System.out.println("AllAnimal构造方法执行");
  27.         }
  28. }


  29. class AllPerson extends AllAnimal{
  30.         static {
  31.                 //此时执行静态代码块吗,错,有父类的话,先加载父类字节码文件,执行父类静态代码块和静态属性,和构造方法类似
  32.                 //程序跳到22行
  33.                 System.out.println("AllPerson静态代码块执行");
  34.                 //这句代码执行完后,代表所需要的字节码文件全部加载进内存,这时加载后面的静态属性后就可以执行构造方法
  35.         }
  36.         //创建父类对象,因为父类中的静态代码块只执行一次,所以直接调用父类构造方法,程序跳到26行
  37.         static AllAnimal aa = new AllAnimal();
  38.         public AllPerson() {
  39.                 //执行到这行会直接调用构造方法中的内容吗,不是,执行之前得加载字节码文件,由类加载器去加载,
  40.                 //随着类加载器的载入,静态属性和静态代码块又得到执行,程序跳到32行
  41.                 System.out.println("AllPerson构造方法执行");
  42.                 //构造方法执行完后,程序跳转到11行
  43.         }
  44. }
复制代码
仔细看我的注释
创建对象需要该对象的字节码文件,此时就必须加载字节码文件,由类加载器去加载,不懂可以去看张老师的高新技术视频,如果该类有父类,就必须先加载父类的字节码文件,加载完最终父类后加载子类字节码文件,不管是静态方法还是非静态方法,你不调用,就得不到运行,静态代码块通过类名调用。非静态代码块通过对象调用
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马