您的位置:首页 > 编程语言 > Java开发

七、Java 如何保证所有变量在使用前都初始化?

2019-01-14 22:58 681 查看
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_37264516/article/details/86187299

局部变量与成员变量的初始化

对于方法体内的局部变量,Java 用一个编译时错误来提醒初始化:

void fun(){
int x;
x++;//报错:i not initialized
}

对于类中的成员变量,在声明类的对象时,每个基本类型的变量都会有一个初始值。

public class initClass{
boolean bool;
char c;
byte b;
short s;
int i;
long l;
float f;
double d;
initClass ref;

void printInitValues(){
System.out.println("boolean:"+bool);
System.out.println("char:"+"["+c+"]");
System.out.println("byte:"+b);
System.out.println("short:"+s);
System.out.println("int:"+i);
System.out.println("long:"+l);
System.out.println("float:"+f);
System.out.println("double:"+d);
System.out.println("initClass:"+ref);
}
}
/*Output:
boolean:false
char:[]
byte:0
short:0
int:0
long:0
float:0.0
double:0.0
initClass:null
*/

对于成员变量,也可以指定初始化值:

public class initClass{
boolean bool = true;
char c = 'a';
byte b = 47;
short s = 0xff;
int i = 888;
long l = 1;
float f = 3.14f;
double d = 3.1415926;

String str = new String("abcfdk");//非基本类型可以用new初始化

int x = fun();//调用函数初始化

int fun(){
return 11;
}
}

用构造方法初始化成员变量

使用构造方法,可以在运行时刻,创建对象时利用构造方法初始化成员变量,非常灵活。

需要注意的是,在构造方法执行前,依旧会先执行自动初始化变量的操作,即下面代码中的

int i
,首先
i
初始化为
0
,接着被构造方法初始化为
20

public class init {
boolean bool;
char c;
byte b;
short s;
int i;
long l;
float f;
double d;
init ref;

public init() {
this.bool = true;
this.c = 'x';
this.b = 1;
this.s = 3;
this.i = 20;
this.l = 999;
this.f = 5.6f;
this.d = 7.28374;
this.ref = new init();
}
}

静态数据的初始化

类中的静态数据,只有在被需要时,才会主动初始化,并且在整个运行过程中只初始化一次。

public class init {
int x;
static {//静态初始化代码块
x = 10;
}
void print(){
System.out.println(x);
x++;
}
public static void main(String [] args){
init u = new init();
u.print();//x = 10

init x = new init();
x.print();//x = 11
}
}

初始化顺序是:先静态变量(是第一次初始化情况下),后非静态变量。

对象创建的过程:

  1. 一个类中除了显示定义的静态域,还有构造方法也是静态方法,当首次创建对象或者首次访问类中的静态域时,Java 解释器必须查找类路径。定位对应的
    .class
    文件。
  2. 然后加载
    .class
    ,执行静态初始化的所有动作。因此静态初始化只在加载
    .class
    时进行一次。
  3. new
    创建对象时,首先在堆上分配足够的空间。
  4. 清空堆上的存储空间,并将类中成员变量初始化为默认值
  5. 执行字段定义时的初始化动作
  6. 执行构造方法。

数组初始化

数组是一种将相同类型的,用一个标识符封装到一起的一个对象序列或者基本类型数据序列

无论是对象数组还是基本类型数组,都有一个固有成员:

length
,可以获得数组内元素的个数。

public static void main(String [] args){
int [] a = {1,2,3,4};//存储空间分配由编译器负责,等价于new

int [] a2;
a2 = a;//这里只是将a2也指向了a所指向的内存块
}

通过

new
创建指定大小的数组

int [] a = new int[10];//此时,数组内元素均默认初始化为0

对象数组即便使用了

new
创建后,依然无法直接使用,因为创建的仅仅是一个对象的引用数组,数组内每个元素并没有指向具体对象,需要赋值具体对象后才能使用。

Integer [] b = {new Integer(1),new Integer(10),3,5};//对象数组初始化
Integer [] c = new Integer[]{new Integer(10),5,8};
Integer [] a = new Integer[10];//创建10个Integer对象的引用数组
for(int i=0; i<a.length; i++){
a[i] = 0;//自动装箱,赋值具体Integer对象。
}

可变参数列表

int print(int... tem){
for(int i : tem){
System.out.println(i);
}
}

可变参数的出现,可以在调用方法时直接传递多个相同类型的参数,不用再封装到数组里,编译器会将这些参数以数组的形式传递到方法内。若没有传递参数,则传递到方法的数组长度为 0。

可变参数列表在重载函数中的问题

void f(int... i){...}
void f(Long... l){...}

上述代码中,当调用时有参数,则编译器能够找到最匹配的一个方法取执行,但是如果像这样没有参数调用时:

f();
,编译器该如何选择呢?

对于这个问题,实际上并不应该在重载函数中使用多个可变参数,解决方案有:

  1. 尽量不使用可变参数
  2. 增加其他非可变参数区分
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐