精华内容
下载资源
问答
  • 2021-10-09 09:59:25

    1、全局int变量(包括有static前缀的)未初始化, 默认值是0。

    2、局部int变量未初始化,默认值未知。(除了加static 前缀的局部变量,因为此时的局部变量是放在静态存储区内的,跟全局变量一样)

    解释:局部变量是存在栈中,数据量大,且生命周期短,若为局部变量进行初始化,开销很大。

    -------所以,我们在定义局部变量的时候,最好直接初始化

    更多相关内容
  • 初始化阶段 在链接得准备阶段进行静态变量得默认值赋值操作 一、面试题:请回答,下面两段代码得执行结果 public class A { static int a ; public static void main(String[] args) { System.out.println(a)...

    类加载准备阶段 类变量赋值


    关键词

    • 加载阶段>链接阶段(验证,准备,解析)>初始化阶段
    • 在链接得准备阶段进行静态变量得默认值赋值操作

    一、面试题:请回答,下面两段代码得执行结果

    public class A {
        
        static int a ;
        public static void main(String[] args) {
          System.out.println(a);
       }
        
    }
    
    public class B {
        
      public static void main(String[] args) {
        int a ;
        System.out.println(a);
      }
        
    }
    

    二、回答

    • 程序1:输出 0
    • 程序2:无法通过编译

    三、剖析

    1. 类加载子系统介绍

    在这里插入图片描述
    1、类加载子系统负责从文件系统或是网络中加载.class文件,class文件在文件开头有特定的文件标识。

    2、把加载后的class类信息存放于方法区,除了类信息之外,方法区还会存放运行时常量池信息,可能还包括字符串字面量和数字常量(这部分常量信息是Class文件中常量池部分的内存映射);

    3、ClassLoader 只负责class文件的加载 ,至于它是否可以运行,则由Execution Engine决定;

    4、如果调用构造器实例化对象,则该对象存放在堆区;

    2. 类加载的执行过程

    在这里插入图片描述我们写的程序经过编译后成为了.class文件,.class文件中描述了类的各种信息,最终都需要加载到虚拟机之后才能运行和使用。而虚拟机如何加载这些.class文件?.class文件的信息进入到虚拟机后会发生什么变化

    类使用的7个阶段
    类从被加载到虚拟机内存中开始,到卸载出内存,它的整个生命周期包括:

    • 加载(Loading)、
    • 验证(Verification)、
    • 准备(Preparation)、
    • 解析(Resolution)、
    • 初始化(Initiallization)、
    • 使用(Using)
    • 卸载(Unloading)

    这7个阶段。其中验证、准备、解析3个部分统称为连接(Linking)

    3. 加载

    加载是类加载的第一个阶段。有两种时机会触发类加载:

    1)预加载

    虚拟机启动时加载,加载的是JAVA_HOME/lib/下的rt.jar下的.class文件,这个jar包里面的内容是程序运行时非常常常用到的,像java.lang.*、java.util.、 java.io. 等等,因此随着虚拟机一起加载。

    2)运行时加载

    虚拟机在用到一个.class文件的时候,会先去内存中查看一下这个.class文件有没有被加载,如果没有就会按照类的全限定名来加载这个类。

    那么,加载阶段做了什么,其实加载阶段做了有三件事情:

    • 获取.class文件的二进制流
    • 将类信息、静态变量、字节码、常量这些.class文件中的内容放入方法区中
    • 在内存中生成一个代表这个.class文件的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。一般这个Class是在堆里的,不过HotSpot虚拟机比较特殊,这个Class对象是放在方法区中的

    4. 链接( 面试题得考点 )

    链接包含三个步骤: 分别是 验证Verification , 准备Preparation , 解析Resolution 三个过程

    1)验证Verification

    连接阶段的第一步,这一阶段的目的是为了确保.class文件的字节流中包含的信息符合当前虚拟机的要求,并且
    会危害虚拟机自身的安全

    Java语言本身是相对安全的语言(相对C/C++来说),但是前面说过,.class文件未必要从Java源码编译而来,可以使用任何途径产生,甚至包括用十六进制编辑器直接编写来产生.class文件。在字节码语言层面上,Java代码至少从语义上是可以表达出来的。虚拟机如果不检查输入的字节流,对其完全信任的话,很可能会因为载入了有害的字节流而导致系统崩溃,所以验证是虚拟机对自身保护的一项重要工作。

    验证阶段将做一下几个工作,具体就不细讲了,这是虚拟机实现层面的问题:

    • 文件格式验证

    • 元数据验证

    • 字节码验证

    • 符号引用验证

    2)准备Preparation

    准备阶段是正式为类变量分配内存并设置其初始值的阶段,这些变量所使用的内存都将在方法区中分配。关于这点,有两个地方注意一下:

    • 这时候进行内存分配的仅仅是类变量(被static修饰的变量),而不是实例变量,实例变量将会在对象实例化的时候随着对象一起分配在Java堆中
    • 这个阶段赋初始值的变量指的是那些不被final修饰的static变量,比如"public static int value = 666",value在准备阶段过后是0而不是666,给value赋值为666的动作将在初始化阶段才进行;比如"public static final int value =666;"就不一样了,在准备阶段,虚拟机就会给value赋值为666。

    注意 :
    这是因为局部变量不像类变量那样存在准备阶段
    类变量有两次赋初始值的过程

    • 一次在准备阶段,赋予初始值(也可以是指定值)
    • 另外一次在初始化阶段,赋予程序员定义的值

    因此,即使程序员没有为类变量赋值也没有关系,它仍然有一个默认的初始值。但局部变量就不一样了,如果没有给它赋初始值,是不能使用的。

    四、总结

    • 类变量在准备阶段进行了默认值赋值操作,后续初始化阶段不进行赋值操作也有默认值,因此程序可以正常运行
    • 局部变量在准备阶段不会进行初始值操作,后续初始化阶段也不赋值则不能使用,编译失败
    展开全文
  • C语言中,未初始化的局部变量到底是多少? 答案往往是: 与编译器有关。 可能但不保证初始化为0。 未确定。 总之,全部都是些一本正经的形而上答案,这很令人讨厌。 但凡一些人给你滔滔不绝地扯编译器,C库,...
  • c语言局部变量默认初始值

    万次阅读 多人点赞 2018-04-09 15:29:48
    C语言中,定义局部变量时如果未初始化,则是随机的,这是为什么呢?定义局部变量,其实就是在...c语言中只有局部变量在未初值时,才是随机数,全局变量和静态变量未初值时编译器会自动将其初始化为0。局部变量...

    C语言中,定义局部变量时如果未初始化,则值是随机的,这是为什么呢?

    定义局部变量,其实就是在栈中通过移动栈指针来给程序提供一个内存空间和这个局部变量名绑定。因为这段内存空间在栈上,而栈内存是反复使用的(脏的,上次用完没清零的),所以说使用栈来实现的局部变量定义时如果不显式初始化,值就是脏的。

    c语言中只有局部变量在未赋初值时,才是随机数,全局变量和静态变量未赋初值时编译器会自动将其初始化为0。局部变量是分配在堆栈上的,而全局变量和静态变量是分配在数据段中的。这个跟程序的内存分配是有关系的。

    展开全文
  • 前几天,有个大佬考了我一个问题:为什么类的成员变量不需要指定值就可以自动赋予初始值,而方法内的局部变量必须指定初始值呢?说实话,这个问题确实难倒我了,之后我在网上一顿操作,终于把这个问题弄得稍微明白...

    【套装4本】java编程思想4第4版+

    402.5元

    包邮

    (需用券)

    去购买 >

    f22ce081e36827da908204eacd0e31c8.png

    前几天,有个大佬考了我一个问题:为什么类的成员变量不需要指定值就可以自动赋予初始值,而方法内的局部变量就必须指定初始值呢?

    说实话,这个问题确实难倒我了,之后我在网上一顿操作,终于把这个问题弄得稍微明白一点了。

    首先我给出一个具体的场景来说明这个事情:

    bVbEQrW

    定义一个Cat类,里面有各种属性,包括8大基本数据类型和String类型,我们把String类视为复杂数据类型。Cat类里面有一个setAge方法。我们在main方法里面给tom这个Cat赋值年龄,结果发现,如果给定的年龄没有赋初始值,编译器会报错:

    bVbEQss

    那我们来看下未给Cat里面的各种属性初始化,各项属性的初始值究竟是怎样的:

    重写一下toString方法:

    bVbEQtd

    然后输出结果为:

    bVbEQtu

    我们能够看到,对于8大基本类型的初始化已经实现了,分别是如图所示的值。对于复杂的类,会赋予null作为默认值。(这里char的默认值为'/u0000'也就是null)

    那么问题来了,为什么Java会有这样的操作呢,为什么不能将方法内的局部变量也自动赋值一个默认值呢?

    首先,我在网上找到了这样的一个答案如下,如果不想看原文,可以直接跳过至引用答案的结尾处直接看我的总结:

    这位作者在读《深入理解Java虚拟机》的时候记录了一个相关知识点。

    类的成员变量有默认初始值,而方法内的局部变量却没有初始值。这个问题涉及到JVM类加载和字节码执行两个阶段,这两个阶段是依次执行的。

    JVM类加载是JVM利用类加载器将class文件加载到JVM的过程,涉及“加载”、“验证”、“”准备“、“”解析“和”初始化“。

    一、类的成员变量初始化   ---在JVM类加载阶段完成

    类的成员变量又分为静态成员变量和非静态成员变量。

    静态成员变量

    静态成员变量会被初始化两次,第一次在“准备”阶段,先进行一次初始化,系统附上默认值;第二次在“初始化”阶段,根据代码中的赋值情况再进行一次初始化。

    例如:

    public static int i =3 ;

    第一次初始化后i的值为0,第二次初始化后,值才为3.

    数据最终存放在方法区中。

    非静态成员变量

    仅“初始化”阶段赋值。根据代码中的赋值情况,代码不赋值直接赋默认值,有赋值则等于代码中的赋值。对象实例化后,该变量随java对象分配到java堆中。

    二、方法区的局部变量没有初始化

    而方法中的局部变量没有初始化步骤,如下图:

    bVbEQtU

    需要在代码中进行初始化。

    bVbEQtV

    ————————————————

    原因就是类方法中的代码,实在字节码执行的时候,才会被运行到,此时局部变量是存储在虚拟机栈-栈帧中的局部变量表中。局部变量定义了但是没有赋值是不能使用的。

    版权声明:本文为CSDN博主「一步一台阶」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

    原文链接:https://blog.csdn.net/liufang...

    这篇帖子主要是说明了两种变量在JVM编译代码的时候把他们放在了哪里。

    JVM加载类的时候,不管是静态类还是非静态类,都会给每个类分配内存,存在堆里面,都有初始化的这一步操作。

    对于方法内的局部变量,由于方法要放到堆栈中(堆栈这个词,其实意义就是栈,习惯称为堆栈,其实和堆没关系),只有字节码执行的时候才会被运行到,所以没有赋值是不能使用的。

    ………………??? 这是什么意思?也就是说,两种变量的存储位置不一样,会对是否初始化有影响,但是没有说明为什么成员变量在堆里就有初始化,方法内局部变量为啥放在堆栈里面,只有执行方法的时候才会被运行到就不能初始化呢?

    然后我就找到另一篇文章如下:

    为什么 Java 中全局变量不一定初始化,局部变量必须初始化?

    作者:Intopass

    链接:https://www.zhihu.com/questio...

    来源:知乎

    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    首先 Java 语言就是这么规定的。

    然后为什么 Java 语言要这么规定呢?有什么内部机理吗?

    可能的原因如下,当我们新建一个对象时,Java会在Heap中申请一块内存区域用以存放类的数据。而成员变量就是类的数据,也是放在这块内存区域中的。只需要JVM在申请内存的时候顺便把整块区域都置为零即可完成初始化,方便快捷。

    而对于方法的局部变量,是在线程的Stack中,当然Stack他也可以帮我们初始化,不过有一个问题。对于有些局部变量,在方法的一开始是没有的,有些在循环中的局部变量是要反复的声明多次的。有些局部变量作用域结束后,另一个局部变量又会占用这个局部变量的位置。

    那么初始化要放在何时呢?当然JVM可以帮我们初始化多次,不过那样或许会带来性能问题。

    for (int i = 0; i < 10; i++) {

    int n;

    if (i % 2 == 0) {

    n = 10;

    } else {

    n = 20;

    }

    }

    像是这个n,我们完全不用JVM帮我们初始化,如果每次循环他都帮我们初始化一次,那么是没有必要的。综上所述,对于局部变量,可能不帮我们初始化是一个不错的选择。(而且JVM实现起来也更容易!!!)

    通过看这位作者的讲解,我们就能够理解得更清楚一些了。为什么堆内的成员变量可以初始化?因为容易,申请内存的时候顺便就实现了初始化。为什么栈内的局部变量不能初始化?因为麻烦,而且没有必要。

    最后,我又看到了一个内容,同知乎页面另一个匿名作者的回答:

    套用《Thinking in Java》作者Bruce Eckel的话

    编译器当然可以为局部变量附一个默认值,但是未初始化的局部变量更有可能是程序员的疏忽,所以采用默认值范围会掩盖这种失误。因此强制程序员提供一个初始值,往往能够帮助找出程序里的缺陷。

    其实我觉得这句话应该是对于为什么局部变量不能够初始化的最合理的解释了吧。

    总结一下,为什么局部变量需要手动初始化?从技术上来讲,局部变量一般来说总量大,生命周期短,JVM进行初始话开销较大;从业务上讲,局部变量一般用于实际问题下的运算,很少会用到默认值,赋值意义不大;从编程思想上讲,局部变量不初始化,而是报错提醒,更有助于程序员减少开发过程中出现缺陷的可能。一举三得,何乐而不为?

    回到开头,所以说大佬就是大佬,随随便便问一个问题,看似是一个小问题,但是深究下去竟然牵扯到这么多深层次的知识点,甚至有点哲学的意义在里面,佩服佩服!

    java 11官方入门(第8版)教材

    79.84元

    包邮

    (需用券)

    去购买 >

    f0f3f55624fb396b1764d42d6df88864.png

    展开全文
  • 1.类成员变量在 类加载 时会被系统...2.但是方法内的局部变量执行进栈操作,这个过程中系统不会初值,而不初值编译器不会通过,就会报错。 3.建议只要定义变量就初值,养成一个好习惯(也建议我自己)。 ...
  • 局部变量不像全局变量可赋初始值, 但可以通过编译指令把指定类型的常量当作变量用, 如: const {$J+} num: Integer = 1; {$J-} begin Inc(num); ShowMessage(IntToStr(num)); {2} end; //或者写作: const {$...
  • C语言局部变量默认初始值

    千次阅读 2019-07-10 22:38:34
    c语言中只有局部变量在未初值时,才是随机数,全局变量和静态变量未初值时编译器会自动将其初始化为0。局部变量是分配在堆栈上的,而全局变量和静态变量是分配在数据段中的。这个跟程序的内存分配是有关系的。 ...
  • 成员变量有默认初始值,而方法内的局部变量却没有初始值。这个问题涉及到JVM类加载和字节码执行两个阶段,这两个阶段是依次执行的。 JVM类加载是JVM利用类加载器将class文件加载到JVM的过程,涉及“加载”、“验证...
  • 局部变量和成员变量的初始值问题

    千次阅读 2018-12-13 10:23:45
    局部变量必须显示给予一个初始值,否则编译无法通过。大家在学习的时候,一般是直接把这个结论直接记下,很少去考虑原因。 所以,这是为什么呢? 比如 在局部变量中,必然是先声明一个变量,再进行赋值。于是...
  • 类的成员变量有默认初始值,而方法内的局部变量却没有初始值。这个问题涉及到JVM类加载和字节码执行两个阶段,这两个阶段是依次执行的。 JVM类加载是JVM利用类加载器将class文件加载到JVM的过程,涉及“加载”、...
  • 注意:java中的局部变量一定要赋初始值。编译运行后就会在控制台会出现。 package edu.xcdq.demo03; import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer; /** */ public class test { public ...
  • 如果在定义变量后没有给它们赋初始值,那么java会给于一个默认的初始化值,但只有类的成员变量才被初始化,而局部变量不会被初始化。如果没有被初始化的变量被操作,java在编译器就会给予错误警告,如果没有被赋予...
  • 如上图所示, 1、全局int变量(包括有static前缀的)未初始化,默认值是0。 2、局部int变量未初始化,默认值未知。...解释:局部变量是存在栈中,数据量大,且生命周期短,若为局部变量进行初始化,开销很大。 ...
  • 上边是两个语句,第一个,声明一个类的成员变量,第二个,对成员变量赋值,而成员变量属于对象,对它的赋值只能由对象来操作,在类中单独对其赋值,当然要报错了。(类里面只能放成员变量和方法吧,赋值是个操作) ...
  • 全局变量有时也需要初始化,而局部变量其实大部分时间都没有初始化。不要把初值与初始化混淆了:初始化是由编译器做的,形成可执行文件后,那些变量的就在软件文件中放着,执行程序时直接使用了;而初值是由C/...
  • delphi 定义变量同时赋值初始值

    千次阅读 2019-02-15 11:31:52
    只有全局变量才能在定义的时候初值,局部变量不可以! var Form1: TForm1; Present: TDateTime; year_ :string= '0'; //只有全局变量才能初值 month_ :string= '0'; day_ :string= '0'; hour_ :string= ...
  • 基本数据类型数值6类 (long/int/short/byte)(double/float) 非数值2类(char,boolean)下面是默认值:0/0/0/0/0.0/0.0/ /false首先 Java 语言就是这么规定的。然后为什么 Java 语言要这么规定...而成员变量就是类的数...
  • 编码时经常会遇到 IDE 对于 “变量未初始化” 的警告,我们不应当忽略此警告,有些时候未初始化的局部变量可能包含了非法。 为什么局部变量初始化? 局部变量的分配和释放:局部变量存在于栈内存区,一个...
  • 一个我们编写的java源码类(机器码)要想被正式运行...在这个过程中,我们会对我们定义的成员变量进行两次初始化,一次默认初值(0,boolean为false),一次我们定义的初值,如: class Test{ int a = 2; }
  • Java变量初始值

    2021-02-12 15:25:26
    Java中的变量如果没有赋值,成员变量默认被初始化,局部变量则不会。对于成员变量 int a; // a的初始值为0如下例中的成员变量a,b,c,dpublic class VariableInitialValue {public static void main(String args[]) {...
  • 全局变量和局部变量初始化问题

    千次阅读 2019-08-23 16:08:42
    现在,我们要讨论的是程序猿或者程序媛需不需要给全局变量和局部变量赋初值的问题。因为全局变量的初始值是系统默认的且是可使用的,因此,全局变量一般不需要自己去赋初值,不过为了养成良好的代码习惯,最好还是赋...
  • 静态局部变量保存在全局数据区,而不是保存在栈中,每次的保持到下一次调用,直到下次。该变量在全局数据区内分配内存;静态局部变量在程序执行到该对象的声明处时被首次初始化,即以后的函数调用不再进行...
  • 实在知乎上看的答案,感觉很好,就转载一下,原文地址: 为什么全局变量无须初始化,局部变量必须初始化? https://www.zhihu.com/question/30516949Intopass回答一:首先 Java 语言就是这么规定的。然后为什么 ...
  • 关于局部变量初始

    千次阅读 2018-10-26 15:22:35
    我们经常被告知:在Java语言规定,局部变量必须要先初始化,然后才能使用。为什么呢? 首先 Java 语言就是这么规定的。其实无论成员变量还是局部变量都要初始化。只是JVM帮我们初始化了成员变量。 第一种解释: ...
  • 今天看到一个面试题,关于变量赋初始是否会报错的题目,瞬间就GG了,怪基础差 import java.util.*; public class test{ public static void main (String[] args){ String str; System.out.println("str=...
  • 函数中静态局部变量a初值,采用上述两种方式时不一样,采用方式1时a是上次结束时的,采用2方式时a=1还是每次都运行,为什么? 初始化和赋值是不同的概念。 只初始化一次,不是只赋值一次。 ...
  • Java成员变量、局部变量的默认值和初始

    千次阅读 多人点赞 2019-07-24 11:54:46
    转载:https://blog.csdn.net/qq_24644517/article/details/82288493 package deep; public class DefaultValue { // 实例成员变量 private boolean bool; private byte b; private short s; private ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 81,401
精华内容 32,560
关键字:

局部变量必须赋初始值