鱼C论坛

 找回密码
 立即注册
查看: 383|回复: 8

类的加载问题?

[复制链接]
最佳答案
0 
发表于 2018-4-16 21:17:58 | 显示全部楼层 |阅读模式
4鱼币
论坛的大神们,有个问题困扰着我,具体看代码:
  1. public class Instance{
  2.     {
  3.         a=6;
  4.     }
  5.     int a=9;
  6.     public static void main(String[] args) {
  7.         System.out.println(new Instance().a);
  8.     }
  9. }
复制代码

类初始化时代码块和成员变量的优先级是相同的,谁在前先执行谁。那么a=6时,a这个变量还没声明啊,怎么会不报错?我javap查看后发现int a跑到了第一行,查资料有说非静态的这些在类加载时会被linit合并,静态的被clinit合并,是否是因为这个? Snipaste_2018-04-16_21-14-54.png

最佳答案
1 
发表于 2018-4-17 06:57:00 From FishC Mobile | 显示全部楼层
跟据变量的生命周期,int a,是全局变量,所以在这个全局范围内在什么地方都可以用,你多注意一下局部变量和全局变量有什么特点,
最佳答案
41 
发表于 2018-4-17 16:29:35 | 显示全部楼层
本帖最后由 ABC23 于 2018-4-17 16:35 编辑

首先代码没问题。a=9。
===============
分析:Java是以class为基本单位组织代码的。首先JVM加载Instance类,同时载入声明的成员变量a=0(基本类型初始化为0)
接着因为代码块的优先级较高(在前面),现将a赋值为6;接着代码顺序执行,a=6覆盖原来的a(两个a实际上指向同一块内存)。
综上,a=9。
===============
关于局部代码块,只要注意『在局部代码块内部声明的变量只存活于代码块内部』就可以了。

...
a = 6;
{
        int a = 9;
}
...
这会抛出一个Error。
最佳答案
0 
 楼主| 发表于 2018-4-19 10:15:57 | 显示全部楼层
ABC23 发表于 2018-4-17 16:29
首先代码没问题。a=9。
===============
分析:Java是以class为基本单位组织代码的。首先JVM加载Instance ...

也就是说,尽管int a是在后面声明的,但是,在加载时它是先被执行的?
能详细说一下为什么会有这种“提前”呢?
最佳答案
41 
发表于 2018-4-19 10:59:49 | 显示全部楼层
ylyl 发表于 2018-4-19 10:15
也就是说,尽管int a是在后面声明的,但是,在加载时它是先被执行的?
能详细说一下为什么会有这种“提 ...

先声明,后使用。这是变量的基本准则。
在Java中,不像C99那样严格。你可以在比较『随意』的地方进行声明,甚至同时声明和使用。
代码是自上而下执行的,所以先执行前面的在执行后面的。想要执行a=6但是没有声明,于是就去找。在后面找到int a = 9;这里拆成两部分看:1)int a,2)a=9,即先声明,后使用。这里我们只要前半句。于是a声明生效,a被初始化为0(因为是基本类型),接着立即把6赋值给a,现在a=6.最后代码接着向下执行,a=9.
最佳答案
0 
 楼主| 发表于 2018-4-19 13:55:24 | 显示全部楼层
ABC23 发表于 2018-4-19 10:59
先声明,后使用。这是变量的基本准则。
在Java中,不像C99那样严格。你可以在比较『随意』的地方进行声 ...

我觉得你说的有点问题,请参看链接https://segmentfault.com/q/1010000012954285
按里面的解释,int a是在之前就已经被加载过了,我查了一些资料,非静态的代码块,成员变量等在类加载的时候会被init方法合并,静态的会被clinit合并,但是具体怎么合并,产生什么效果,中文资料全都语焉不详,英文的看不懂。。。你看我问题里的图和链接里的图,确实在字节码里,int a跑到前面去了,但是不是init起的作用就不得而知了
最佳答案
0 
 楼主| 发表于 2018-4-19 14:08:39 | 显示全部楼层
ABC23 发表于 2018-4-19 10:59
先声明,后使用。这是变量的基本准则。
在Java中,不像C99那样严格。你可以在比较『随意』的地方进行声 ...

我大概知道了,int a这个声明早在类加载时就已经声明了,给了默认值0,clinit和init与这个并没有关系,合并的是赋值语句。这个问题因该是类在加载时做的某种“优化”。
最佳答案
41 
发表于 2018-4-19 19:37:36 | 显示全部楼层
ylyl 发表于 2018-4-19 14:08
我大概知道了,int a这个声明早在类加载时就已经声明了,给了默认值0,clinit和init与这个并没有关系,合 ...

有什么问题?
最佳答案
0 
 楼主| 发表于 2018-4-19 21:25:45 | 显示全部楼层

具体就是,int a到底是怎么跑到前面去的
*滑块验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

小甲鱼强烈推荐上一条 /1 下一条

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号 )

GMT+8, 2018-7-23 11:58

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表