-
2021-02-28 18:17:23
1、成员变量
成员变量有默认初始值,而方法内的局部变量却没有初始值。这个问题涉及到JVM类加载和字节码执行两个阶段,这两个阶段是依次执行的。
JVM类加载是JVM利用类加载器将class文件加载到JVM的过程,涉及“加载”、“验证”、“”准备“、“”解析“和”初始化“。
一、类的成员变量初始化 ---在JVM类加载阶段完成
类的成员变量又分为静态成员变量和非静态成员变量。
静态成员变量
静态成员变量会被初始化两次,第一次在“准备”阶段,先进行一次初始化,系统附上默认值;第二次在“初始化”阶段,根据代码中的赋值情况再进行一次初始化。
例如:
public static int i =3 ;
第一次初始化后i的值为0,第二次初始化后,值才为3.
数据最终存放在方法区中。
非静态成员变量
仅“初始化”阶段赋值。根据代码中的赋值情况,代码不赋值直接赋默认值,有赋值则等于代码中的赋值。对象实例化后,该变量随java对象分配到java堆中。
2、局部变量
当我们新建一个对象时,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实现起来也更容易!!!)
3、总结
套用《Thinking in Java》作者Bruce Eckel的话
编译器当然可以为局部变量附一个默认值,但是未初始化的局部变量更有可能是程序员的疏忽,所以采用默认值范围会掩盖这种失误。因此强制程序员提供一个初始值,往往能够帮助找出程序里的缺陷。
总结一下,为什么局部变量需要手动初始化?从技术上来讲,局部变量一般来说总量大,生命周期短,JVM进行初始话开销较大;从业务上讲,局部变量一般用于实际问题下的运算,很少会用到默认值,赋值意义不大;从编程思想上讲,局部变量不初始化,而是报错提醒,更有助于程序员减少开发过程中出现缺陷的可能
更多相关内容 -
Java中static静态变量的初始化完全解析
2020-09-02 04:24:44static所声明的变量在Java中有一个初始化的先后顺序,带着这个问题接下来我们就来进行Java中static静态变量的初始化完全解析: -
C++11静态局部变量的初始化时机
2021-03-15 10:43:49static Singleton *GetInstance() // 如果多次调用此函数,单例类的初始化也只会执行一次(即只会为这个静态局部对象分配一次内存空间) { static Singleton locla_s; return &locla_s; } templ.#include <iostream> using namespace std; // 基于C++11静态局部变量的懒汉式单例实现 class Singleton { public: static Singleton *GetInstance() // 如果多次调用此函数,单例类的初始化也只会执行一次(即只会为这个静态局部对象分配一次内存空间) { static Singleton locla_s; return &locla_s; } template<typename T> T GetSquare(T number); private: int x_; int y_; static Singleton *local_instance; Singleton() : x_(10), y_(10) { cout << "构造" << endl; }; ~Singleton() { cout << "析构" << endl; } }; template<typename T> T Singleton::GetSquare(T number) { return number * number; } int main() { { cout << "first time to use single : " << endl; cout << Singleton::GetInstance()->GetSquare(10) << endl; cout << "end first use ...... " << endl; } { cout << "second time to use single : " << endl; cout << Singleton::GetInstance()->GetSquare(20) << endl; cout << "end second use ...... " << endl; } return 0; }
C++11标准关于局部静态变量初始化,有这么几点要求:
1. 变量在代码第一次执行到变量声明的地方时初始化。
2. 初始化过程中发生异常的话视为未完成初始化,未完成初始化的话,需要下次有代码执行到相同位置时再次初始化。
3. 在当前线程执行到需要初始化变量的地方时,如果有其他线程正在初始化该变量,则阻塞当前线程,直到初始化完成为止。
4. 如果初始化过程中发生了对初始化的递归调用,则视为未定义行为。
-
静态局部变量初始化
2019-03-07 11:17:06原以为会每次调子函数时,都会初始化静态局部变量。实际并非如此 #include void key(void) { //static unsigned char key_up =1; unsigned char key_up =1; printf("key_up = %d \n", key_up); key_up = ...mask一下一直以来的一个误区
#include <stdio.h> void key(void) { static unsigned char key_up =1; printf("key_up = %d \n", key_up); key_up = 0; printf("key_up = %d \n", key_up); } int main(void) { key(); key(); return 0; }
原以为会每次调子函数时,都会初始化静态局部变量。实际并非如此
#include <stdio.h> void key(void) { //static unsigned char key_up =1; unsigned char key_up =1; printf("key_up = %d \n", key_up); key_up = 0; printf("key_up = %d \n", key_up); } int main(void) { key(); key(); return 0; }
-
函数中的局部静态变量只能初始化一次
2018-08-22 09:52:411、 已经初始化的全局变量存放与data数据段;未初始化的全局变量存放与bss数据段。 2、 静态的全局变量存放与data数据段 3、 局部变量存放在栈上。 4、 静态局部变量,并不是在调用函数时分配函数...#include <iostream> using namespace std; int A1() { static int a = 10; a++; cout << a << endl; return a; } int main(int argc, const char * argv[]) { A1(); A1(); A1(); int a1=A1(); cout << "a1="<< a1 << endl; return 0; }
结果:
11 12 13 14 a1=14
全局变量、静态局部变量、静态全局变量都在静态存储区分配空间,而局部变量在栈分配空间。
全局变量本身就是静态存储方式,静态全局变量当然也是静态存储方式。这两者在存储方式上没有什么不同。区别在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。而静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其他源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其他源文件中引起错误。
1、静态变量会被放在程序的静态数据存储区里,这样可以在下一次调用的时候还可以保持原来的赋值。这一点是他与堆栈变量和堆变量的区别。
2、变量用static告知编译器,自己仅仅在变量的作用域范围内可见。这一点是他与全局变量的区别。
从以上分析可以看出,把局部变量改变为静态变量后是改变了他的存储方式,即改变了他的生存期。把全局变量改变为静态变量后是改变了他的作用域,限制了他的使用范围,因此static这个说明符在不同的地方起的作用是不同的。
不同类型的变量在内存中的位置:
1、 已经初始化的全局变量存放与data数据段;未初始化的全局变量存放与bss数据段。
2、 静态的全局变量存放与data数据段
3、 局部变量存放在栈上。
4、 静态局部变量,并不是在调用函数时分配函数返回时释放,而是像全局变量一样静态分配,存放data数据段,但它的作用域在函数中起作用。
下图是内存中的简要分布图,可以更直观的理解个类型变量在内存中的存放位置,图1。
-
C++中静态变量的初始化时间
2021-11-05 14:33:55本文表述了C++中静态变量的初始化时机 -
PHP static局部静态变量和全局静态变量总结
2020-12-19 03:46:33即使局部静态变量定义时没有赋初值,系统会自动赋初值0(对数值型变量)或空字符(对字符变量);静态变量的初始值为0。4.当多次调用一个函数且要求在调用之间保留某些变量的值时,可考虑采用静态局部变量。虽然用... -
c++全局变量和静态局部变量初始化的时间
2020-02-14 14:31:53c++全局变量和静态局部变量初始化的时间 1.全局变量初始化在主函数之前 2.静态局部变量初始化在第一次调用这个静态局部变量之前 #include <iostream> using namespace std; class A { public: A(int a):m_a... -
全局变量,局部静态变量初始化以及类静态成员变量初始化
2016-07-05 11:32:54全局变量、文件域的静态...局部静态变量(一般为函数内的静态变量)在第一次使用时分配内存并初始化。这里的变量包含内置数据类型和自定义类型的对象。 class B{ public: B() { cout ; } ~B() { cout << "B -
为什么Java中全局变量不一定初始化,局部变量必须初始化?
2021-03-13 07:06:40前几天,有个大佬考了我一个问题:为什么类的成员变量不需要指定值就可以自动赋予初始值,而方法内的局部变量就必须指定初始值呢?说实话,这个问题确实难倒我了,之后我在网上一顿操作,终于把这个问题弄得稍微明白... -
静态变量初始化的时机
2018-09-16 22:29:20静态变量的内存分配和初始化 对于C语言的全局和静态变量,不管是否被初始化,其内存空间都是全局的;如果初始化,那么初始化发生在任何代码执行之前,属于编译期初始化。由于内置变量无须资源释放操作,仅需要回收... -
C++局部静态变量在什么时候分配内存和初始化?
2021-05-20 07:48:00静态变量的内存分配和初始化对于C语言的全局和静态变量,不管是否被初始化,其内存空间都是全局的;如果初始化,那么初始化发生在任何代码执行之前,属于编译期初始化。由于内置变量无须资源释放操作,仅需要回收... -
C++11中静态局部变量初始化的线程安全性
2021-02-27 13:49:48C++11 静态 局部变量 初始化 线程安全 -
c++静态局部变量和静态函数示例
2021-01-20 06:30:58在函数体内定义了一个变量,每当程序运行到该语句时都会给该局部变量...静态局部变量在程序执行到该对象的声明处时被首次初始化,即以后的函数调用不再进行初始化(这一点非常的重要);静态局部变量一般在声明处初始化 -
Java 静态变量何时初始化?
2021-02-26 15:47:16小编典典从请参阅Java静态变量方法:它是一个属于类而不属于对象(实例)的变量静态变量在执行开始时仅初始化一次。在初始化任何实例变量之前,将首先初始化这些变量该类的所有实例共享一个副本静态变量可以通过类名... -
C#中static静态变量的用法实例
2020-12-31 03:18:46本文实例讲述了C#中static静态变量的用法。分享给大家供大家参考。具体如下: 使用 static 修饰符声明属于类型本身而不是属于特定对象的静态成员static修饰符可用于类、字段、方法、属性、运算符、事件和构造函数,... -
Java 类变量有默认值,可以不初始化;但局部变量必须要初始化
2019-03-15 11:47:17局部变量定义后,必须初始化,即赋值,才能使用(它没有默认值)。 而类变量定义后可以不初始化,因为它有默认值。 类变量(实例变量):定义在类中,方法体之外。成员变量前面加 static 修饰符。 局部变量:定义在... -
【C++】全局变量和静态变量自动初始化0
2021-08-10 22:42:32静态变量与全局变量的初始化静态和全局变量的初始化默认初始化规则 静态和全局变量的初始化 为初始化的全局变量和静态变量 编译器会同等处理, 放入BSS...全局变量和静态变量(包括局部静态变量)会自动初始化为0 ... -
C语言全局变量和静态全局变量和局部变量和静态局部变量在初始化和未初始化时生存期和作用域的具体情况怎么...
2019-09-15 07:46:25最近看《C程序设计》第五版唐浩强著对静态局部变量有这样一段: > 对静态局部变量是在编译时赋初值的,即只赋初值一次,在程序运行时它已有初值。以后每次调用函数时不再重新赋初值而只是保留上次函数调用结束时的... -
C/C++中全局变量,静态局部变量,局部变量的初始化问题
2017-07-20 11:36:48什么时候初始化 根据 C++ 标准,全局变量的初始化要在 main 函数执行前完成,常识无疑,但是这个说法...答案是既有编译时,也可能会有运行时(seriously), 从语言的层面来说,全局变量的初始化可以划分为以下两 -
关于Java:何时初始化静态变量?
2021-03-16 14:11:38我想知道何时将静态变量初始化为其默认值。加载类时是否创建(分配)了静态var是否正确,然后执行静态初始化程序和声明中的初始化?在什么时候给出默认值? 这导致前向参考的问题。另外,如果您可以参考"为什么不及时... -
全局变量和静态(全局和局部)变量 什么时候初始化?
2019-09-28 23:11:52全局变量和静态(全局和局部)变量 什么时候初始化? 本文链接:https://blog.csdn.net/sunny04/article/details/18605273 1. 静态变量的初始化是在编译时进行,变量的赋值是在函数或程序运行时进行。 2. 静态变量只... -
g++中的局部静态变量的初始化机制及线程安全
2011-08-03 18:20:46g++中的局部静态变量的初始化机制及线程安全 -
C++局部变量和全局变量的初始化
2020-03-02 23:17:18当局部变量被定义时,系统不会对其初始化,此时局部变量的初始值未定义,必须自行对其初始化。定义全局变量时,系统会自动初始化为下列值: -
C++静态类型成员变量的初始化顺序(单例模式)
2022-04-12 20:28:00对编译器来说,静态成员变量的初始化顺序和析构顺序是一个未定义的行为 #include <string> #include <iostream> using namespace std; class Base{ public: static int b; static int a; }; int ... -
C语言基础入门48篇_44_静态局部变量、静态全局变量、静态函数(静态局部变量只被初始化一次,保留变量值、...
2021-12-08 21:46:56静态局部变量、静态全局变量、静态函数(静态局部变量只被初始化一次,保留变量值、静态全局变量是加了作用域的全局变量、静态函数亦是加了作用域的函数) -
Java中成员变量、局部变量、全局变量、静态变量存在位置及初始化
2018-10-31 11:34:53静态属性:随类的存在而存在,是在类加载的初始化 非静态属性:随实例的属性存在而存在。 局部变量: 局部变量不能加static,包括protected, private, public这些也不能加。局部变量保存在栈中。 局部编程必须在... -
C语言静态变量初始化问题
2018-02-10 12:45:45书上的解释是,用static修饰的变量会自动初始化。 为什么会被初始化呢?首先我们看一段话: 可执行程序和内存映像的区别在于:可执行程序位于磁盘上,内存映像位于内存中,可执行程序没有堆栈,可执行程序虽然也... -
C++中 静态局部变量实例详解
2020-12-26 00:46:474.首次初始化时赋值生效,以后的初始化赋值自动跳过 如 void fn() { static n=10; cout<<n<<endl; n++; } 这里的n是一个静态局部变量,只有第一执行fn函数时会调用static n=10,以后都不会调用 ...