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.cnblogs.com/QG-whz/p/4473384.html 我以前的总结放在这里挺合适的。

回到篇首的话。

java尽力保证:所有变量在使用前都能得到恰当的初始化(《java编程思想》)

java在变量初始化上,普通变量以编译错误、成员变量以默认初始化等手段,尽力使所有的变量在使用前都可得到初始化,在安全性上大大强于C++。

java与C++变量初始化的对比的更多相关文章

  1. java非静态变量初始化

    java费静态变量的初始化分为两种情况,一种是局部变量,一种是类的域. 对于类的域,java在类初始化时,会为变量赋一个初始值.对于基本数据类型,java会将初始值设置为二进制0,具体为将boolea ...

  2. JAVA之成员变量初始化

    java中成员变量的初始化,如果是普通成员变量可以赋初值,如果没赋初值,则系统会自动赋初值.而对于局部变量必须手动赋初值. package MyText2; public class MyText1 ...

  3. Java中类成员变量初始化顺序

    一. 定义处默认初始化vs构造函数中初始化 java中类成员变量支持在声明处初始化,也可以在构造函数中初始化,那么这两者有什么区别呢?看下面例子 public class FieldsInit { p ...

  4. Java类的变量初始化顺序

    大家在去参加面试的时候,经常会遇到这样的考题:给你两个类的代码,它们之间是继承的关系,每个类里只有构造器方法和一些变量,构造器里可能还有一段代码对变量值进行了某种运算,另外还有一些将变量值输出到控制台 ...

  5. Java的成员变量初始化

    对于方法里面的成员变量,Java要求程序员强制提供一个初始化的值.比如下面这个方法就会出错: public class Breakyizhan{ public void Z(){ int z; z++ ...

  6. Java静态方法,静态变量,初始化顺序

    1. 静态方法: 成员变量分为实例变量和静态变量.其中实例变量属于某一个具体的实例,必须在类实例化后才真正存在,不同的对象拥有不同的实例变量.而静态变量被该类所有的对象公有(相当于全局变量),不需要实 ...

  7. Java的静态变量初始化的坑

    在网上看到一个很有意思的题目,题目如下 class SingleTon { private static SingleTon singleTon = new SingleTon(); public s ...

  8. Java类变量和成员变量初始化过程

    一.类的初始化 对于类的初始化:类的初始化一般只初始化一次,类的初始化主要是初始化静态成员变量. 类的编译决定了类的初始化过程. 编译器生成的class文件主要对定义在源文件中的类进行了如下的更改: ...

  9. Java 类的实例变量初始化的过程 静态块、非静态块、构造函数的加载顺序

    先看一道Java面试题: public class Baset { private String baseName = "base"; // 构造方法 public Baset() ...

随机推荐

  1. C 函数参数 char **s与char *s[]

    本文同时发表在https://github.com/zhangyachen/zhangyachen.github.io/issues/126 先来看一个小例子 : 编写函数遍历一个整型数组的元素,数组 ...

  2. PipeHttp 测试工具使用

      以下简单介绍下参数工具的使用     GitHub地址: https://github.com/lulianqi/PipeHttp/ (工程地址) https://github.com/lulia ...

  3. seo我告诉你

    seo我告诉你,这回seo真的告诉你百度云链接 链接:http://pan.baidu.com/s/1qYpM9y8 密码:mad6 seo优化教程:

  4. Yum database disk image is malformed

    使用 yum update 时使用Ctrl+C 后,再用yum 安装其他软件的时候收到:Yum database disk image is malformedyum clean dbcache 清除 ...

  5. 分享非常好用的前端分页js工具类 灵活 简单易懂

    分享自己封装的前端分页js工具类  下面是默认样式效果截图 可以随意更改js及css 很灵活 /** * pageSize, 每页显示数 * pageIndex, 当前页数 * pageCount 总 ...

  6. 区分javascript中的toString(),toLocaleString(),valueOf()方法

    首先我们随意创建一个对象,这很简单,打开FF浏览器的Firebug切换到控制台或者打开webkit浏览器的审查元素功能. 输入以下内容: var obj1=[1,2,3,4,5] var obj2=[ ...

  7. 关于 const 的一点小研究

    在饱受 var 的折磨之后,ES6 终于推出了新的定义变量的方法:let 和 const 和 var 相比,let 和 const 有了自己的作用域,let 用于定义变量,而 const 用于定义常量 ...

  8. ES6 modules 详解

    概述 历史上,JavaScript 一直没有模块(module)体系,无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来.其他语言都有这项功能,比如 Ruby 的require.Pytho ...

  9. Center OS 7 安装 $$

    资料来自网络,收集整理做个备忘 1. 安装Python # yum install python-setuptools && easy_install pip 2. 安装$$ # pi ...

  10. jsp 之 解决mysql不是内部或外部命令问题

    安装Mysql后,当我们在cmd中敲入mysql时会出现'Mysql'不是内部或外部命令,也不是可运行的程序或其处理文件. 打开我的电脑在我的电脑右键中选择属性,然后单击选择高级系统设置. 在系统属性 ...