ylyl 发表于 2018-4-16 21:17:58

类的加载问题?

论坛的大神们,有个问题困扰着我,具体看代码:public class Instance{
    {
      a=6;
    }
    int a=9;
    public static void main(String[] args) {
      System.out.println(new Instance().a);
    }
}
类初始化时代码块和成员变量的优先级是相同的,谁在前先执行谁。那么a=6时,a这个变量还没声明啊,怎么会不报错?我javap查看后发现int a跑到了第一行,查资料有说非静态的这些在类加载时会被linit合并,静态的被clinit合并,是否是因为这个?

那皇沫路 发表于 2018-4-17 06:57:00

跟据变量的生命周期,int a,是全局变量,所以在这个全局范围内在什么地方都可以用,你多注意一下局部变量和全局变量有什么特点,

ABC23 发表于 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。

ylyl 发表于 2018-4-19 10:15:57

ABC23 发表于 2018-4-17 16:29
首先代码没问题。a=9。
===============
分析:Java是以class为基本单位组织代码的。首先JVM加载Instance ...

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

ABC23 发表于 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.

ylyl 发表于 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起的作用就不得而知了

ylyl 发表于 2018-4-19 14:08:39

ABC23 发表于 2018-4-19 10:59
先声明,后使用。这是变量的基本准则。
在Java中,不像C99那样严格。你可以在比较『随意』的地方进行声 ...

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

ABC23 发表于 2018-4-19 19:37:36

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

有什么问题?

ylyl 发表于 2018-4-19 21:25:45

ABC23 发表于 2018-4-19 19:37
有什么问题?

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

茗侦探@可乐 发表于 2018-11-26 21:06:06

不错的问题

破灬王 发表于 2018-11-27 16:23:06

a = 6啥玩意? 不报错才怪

chun888 发表于 2019-3-2 19:57:28

那么简单的问题.

chun888 发表于 2019-3-2 19:58:23

类加载,代码块就执行,a没声明
页: [1]
查看完整版本: 类的加载问题?