QQ登录

只需一步,快速开始

登录 | 立即注册 | 找回密码

主题

帖子

荣誉

VIP至尊会员

Rank: 15Rank: 15Rank: 15

积分
57
查看: 100|回复: 8

类的加载问题?

[复制链接]
最佳答案
0 
累计签到:8 天
连续签到:1 天
ylyl 发表于 4 天前 1008 | 显示全部楼层 |阅读模式
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

楼层
跳转到指定楼层
最佳答案
0 
累计签到:6 天
连续签到:6 天
那皇沫路 发表于 3 天前 From FishC Mobile | 显示全部楼层
跟据变量的生命周期,int a,是全局变量,所以在这个全局范围内在什么地方都可以用,你多注意一下局部变量和全局变量有什么特点,
最佳答案
2 

尚未签到

ABC23 发表于 3 天前 | 显示全部楼层
本帖最后由 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 
累计签到:8 天
连续签到:1 天
ylyl  楼主| 发表于 昨天 10:15 | 显示全部楼层
ABC23 发表于 2018-4-17 16:29
首先代码没问题。a=9。
===============
分析:Java是以class为基本单位组织代码的。首先JVM加载Instance ...

也就是说,尽管int a是在后面声明的,但是,在加载时它是先被执行的?
能详细说一下为什么会有这种“提前”呢?
最佳答案
2 

尚未签到

ABC23 发表于 昨天 10:59 | 显示全部楼层
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 
累计签到:8 天
连续签到:1 天
ylyl  楼主| 发表于 昨天 13:55 | 显示全部楼层
ABC23 发表于 2018-4-19 10:59
先声明,后使用。这是变量的基本准则。
在Java中,不像C99那样严格。你可以在比较『随意』的地方进行声 ...

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

我大概知道了,int a这个声明早在类加载时就已经声明了,给了默认值0,clinit和init与这个并没有关系,合并的是赋值语句。这个问题因该是类在加载时做的某种“优化”。
最佳答案
2 

尚未签到

ABC23 发表于 昨天 19:37 | 显示全部楼层
ylyl 发表于 2018-4-19 14:08
我大概知道了,int a这个声明早在类加载时就已经声明了,给了默认值0,clinit和init与这个并没有关系,合 ...

有什么问题?
最佳答案
0 
累计签到:8 天
连续签到:1 天
ylyl  楼主| 发表于 昨天 21:25 | 显示全部楼层

具体就是,int a到底是怎么跑到前面去的

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

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

    移动客户端下载(未启用)
    微信公众号

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

Copyright 2018 鱼C论坛 版权所有 All Rights Reserved.

Powered by Discuz! X3.1 Copyright
© 2001-2018 Comsenz Inc.    All Rights Reserved.

小黑屋|手机版|Archiver|鱼C工作室 ( 粤公网安备 44051102000370号 | 粤ICP备11014136号

GMT+8, 2018-4-20 05:35

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