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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© HM马明宇 中级黑马   /  2013-4-1 03:52  /  1992 人查看  /  9 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 HM马明宇 于 2013-4-1 22:21 编辑

问题在注释里:
  1. /**
  2. * 近日对类中方法的加载有些疑问:
  3. * 通过实践发现,方法无论是否静态,皆可调用(编写时)在其位置之下的方法
  4. * 不过,据我所知程序是按照从上往下的顺序进行执行的(循环等特殊条件除外)
  5. * 那么,问题就来了(当然,类的加载顺序是先加载静态对象(变量和函数)再加载非静态对象的(变量和函数))
  6. *
  7. * 首先我们知道通过静态方法中不能使用非静态对象
  8. * 据此我可以推断方法中的方法体在加载时肯定也要被检验
  9. * 但是为何(普通静态都一样)方法1可以调用方法2?
  10. * 按照程序的执行顺序,(此处以静态方法举例)虽然静态方法2也是静态方法,但是其位置在方法1之下啊
  11. * 加载到方法1的时候,在平常看来方法2还没加载,为什么这样不报错?
  12. * 类中同种(即要么都静态,要么都不静态)方法的的加载是一个什么机制?
  13. */
  14. class Test {
  15. /**
  16. * 普通方法1
  17. */
  18. void pumethod1() {
  19. this.pumethod2();// 普通方法中,方法1可以调用方法2
  20. }

  21. /**
  22. * 普通方法2
  23. */
  24. void pumethod2() {}

  25. /**
  26. * 静态方法1
  27. */
  28. static void method1() {
  29. /**
  30. * 此处在编译中会报错,因为加载本静态方法(method1())时,
  31. * 还没有加载下面这个非静态方法,所以编译报错,
  32. * 由此可判断, 编译时方法中的方法体也是要经过检验的
  33. */
  34. pumethod1();


  35. method2();// 静态方法中,方法1可以调用方法2
  36. }

  37. /**
  38. * 静态方法2
  39. */
  40. static void method2() {}
  41. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

9 个回复

倒序浏览
当jvm加载类文件的时候,用static的成员就已经存在了,是不按顺序,同时加载进内存的方法区内,所以不论方法是在上还是在下面,它都能找到,你还可以这么想,如果 是按顺序的话,方法一先进来了,在调用方法二,这时方法二也就进来了,它就可以调用了,其实是同时加载进内存的,

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

回复 使用道具 举报
建议多看看构造代码块,静态代码块,以及静态方法的加载,

非静态方法的执行一般是涉及到被调用的时候,就会先加载并执行一遍,没有什么先后的
回复 使用道具 举报
非静态方法用来被对象调用的,即建立对象后才会存在该方法。而静态方法是随着类加载而加载,即只要类存在静态方法就有....

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

回复 使用道具 举报
你说的是编译过程报错,因为编译过程是检验文件的语法是否正确,并把相关的java问价编译成类文件。而类的加载时在运行时。
当用java命令运行一个文件时,虚拟机先把java命令后的那个类的加载到内存中,加载完成后才开始运行的;先运行类中的静态代码块(若有多个,则按照代码出现的先后顺序执行),然后才运行主函数;若主函数调用的是本类中的成员,则直接在本类中寻找即可,若调用其他类的成员,则此时就先开始把那个类加载到内存中,然后才使用它的成员(包括使用其构造方法构造一个该类对象)。
若还有疑问,可看下java虚拟机执行机制http://wenku.baidu.com/view/2e68354a852458fb770b56c5.html
回复 使用道具 举报
你说的是编译过程报错,因为编译过程是检验文件的语法是否正确,并把相关的java文件编译成类文件。而类的加载过程是在运行时。
当用java命令运行一个文件时,虚拟机先把java命令后的那个类的加载到内存中,加载完成后才开始运行的(先加载后运行);先运行类中的静态代码块(若有多个,则按照代码出现的先后顺序执行),然后才运行主函数;若主函数调用的是本类中的成员,则直接在本类中寻找即可,若调用其他类的成员,则此时就先开始把那个相关的类加载到内存中,然后才使用它的成员(包括使用其构造方法构造一个该类对象)。
若还有疑问,可看下java虚拟机执行机制http://wenku.baidu.com/view/2e68354a852458fb770b56c5.html

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

回复 使用道具 举报
细节加载和执行先后顺序,也可以加我QQ私聊。
回复 使用道具 举报
编译过程中 加载类 
运行过程中 执行类 
时间上有先后顺序 所以无关空间顺序

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

回复 使用道具 举报
刘策 发表于 2013-4-1 07:11
当jvm加载类文件的时候,用static的成员就已经存在了,是不按顺序,同时加载进内存的方法区内,所以不论方 ...

同时加载的是方法名么?方法体中的内容呢?总得有个加载时间吧?
回复 使用道具 举报
各位楼上的亲们,解释的有点空泛啊,没有说道点子上
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马