内容简介:Java与C++变量初始化的对比
Java尽力保证:所有变量在使用前都能得到恰当的初始化
①函数/方法局部变量的初始化
在C/C++中,变量的初始化还是得依赖于 程序员 的自觉性。对于函数局部变量,编译器不会为基本类型赋予默认初始值,新手经常会使用未初始化的指针访问内存,导致程序崩溃。对于类对象,编译器将使用类的默认构造函数对对象进行初始化。而在 Java 中,对于方法的局部变量,Java以编译时错误来保证变量在使用前都能得到恰当的初始化。
void f(){ int i ; i ++ ; //Error- - i not initialized }
尽管java编译器也可以为方法的局部变量赋予一个初值,但局部变量未初始化更有可能是程序员的疏忽,采用默认值反而会掩盖这种错误。
②类数据成员的初始化
C++程序员刚接触到java的类时可能会很不习惯,java类的数据成员居然可以在定义时就初始化:
public class InitialValues{ boolean bool = true; char ch = ‘x’; int i = 999; double d = 3.14; Depth d = new Depth(); }
这种方式在java中称为 指定初始化 。在指定初始化之前,编译器还会为这些数据成员进行 默认初始化 ,实际上是把刚分配的对象内存都置零。
// java数据成员的默认初始化 public class InitialValues{ boolean t; //flase char c; //[] short s; //0 byte b; //0 int i; //0 long l; //0 float f; //0.0 double d; //0.0 }
在对象里定义一个引用,且不将其初始化时,默认初始化为null。这种默认初始化的实现是,在创建(new)一个对象时,在堆上对对象分配足够的空间之后,这块存储空间会被清零,这样就自动把基本类型的数据成员都设置成了默认值。默认初始化动作之后,才执行指定初始化。也就是说下面的i经历过被初始化为0后,再赋值为999的过程。
public class InitialValues{ int i = 999; }
java也可以使用构造函数来进行初始化,但构造函数的初始化无法阻止指定初始化和默认初始化的进行,而且总是在它们之后,才会执行构造函数初始化。总结起来说,java中数据成员的初始化过程是:
- ① 先默认初始化
- ② 进行定义处的初始化(指定初始化)
- ③ 构造函数初始化
C++禁止在定义数据成员时就进行指定初始化,而且C++也没有默认初始化。有人会问,下面这段代码不是默认初始化了吗?
class Test { public: int i; double b; char ch; }; int main() { Test *t = new Test(); cout << t->b; //输出0 cout << t->i; //输出0 cout << t->ch; //输出[] return 0; }
这实际上是C++的默认构造函数进行的构造函数初始化。当类没有构造函数时,编译器会为类声明并实现一个默认构造函数,默认构造函数将数据成员初始化为默认值。所以C++数据成员的初始值,只能依赖:
- 成员初始化列表
- 构造函数
成员初始化列表与java的指定初始化相似,也是在进入构造函数函数体之前,对数据成员进行的初始化。在数据成员的初始化顺序上,java与C++倒是一致的,定义的顺序决定了初始化的顺序。
关于static成员的初始化
在java中不允许有static的局部变量,只能够有static的域,如static数据成员。static数据成员在对象被第一次创建时才会被实例化,而且只实例化一次。例如:
class StaticTest{ int _a ; StaticTest (int a ){ _a = a; System.out.println("StaticTest("+a+")"); } } class Test{ static StaticTest st1= new StaticTest(1); StaticTest nonSt = new StaticTest(0); static StaticTest st2= new StaticTest(2); } public class Main { public static void main(String[] args) throws Throwable { Test t = new Test(); //直到这个时候, st1与st2才会被实例化 } } //程序输出 StaticTest(1) StaticTest(2) StaticTest(0)
从输出可以看出在Java中,初始化顺序是这样的:先初始化静态数据成员,再初始化非静态数据成员。
在C++中,static数据成员必须在类之外初始化。关于C++的static, 见 http://www.linuxidc.com/Linux/2018-01/150578.htm 。
回到篇首的话。
Java尽力保证:所有变量在使用前都能得到恰当的初始化(《Java编程思想》) pdf下载见 http://www.linuxidc.com/Linux/2014-08/105403.htm
Java在变量初始化上,普通变量以编译错误、成员变量以默认初始化等手段,尽力使所有的变量在使用前都可得到初始化,在安全性上大大强于C++。
本文永久更新链接地址 : http://www.linuxidc.com/Linux/2018-01/150577.htm
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- c++ 静态变量初始化测验
- Golang Tips: 变量的声明与初始化
- Go语言学习(3) - 变量与初始化
- go 变量声明初始化、new、make
- iOS中定义变量是否初始化的区别
- Go语言笔记 | 03-变量的声明和初始化
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Tomcat架构解析
刘光瑞 / 人民邮电出版社 / 2017-5 / 79.00元
本书全面介绍了Tomcat的架构、各组件的实现方案以及使用方式。包括Tomcat的基础组件架构以及工作原理,Tomcat各组件的实现方案、使用方式以及详细配置说明,Tomcat与Web服务器集成以及性能优化,Tomcat部分扩展特性介绍等。读者可以了解应用服务器的架构以及工作原理,学习Tomcat的使用、优化以及详细配置。一起来看看 《Tomcat架构解析》 这本书的介绍吧!
图片转BASE64编码
在线图片转Base64编码工具
SHA 加密
SHA 加密工具