相信大家都遇到过变量未及时赋值而产生的错误,现在就学习一下java初始化的内容。
1初始化默认值
类的数据成员是基本类型,会有一个初始值。
示例:
public class InitDefault{
boolean b;
char c;
byte by;
short s;
int i;
long l;
float f;
double d;
InitDefault reference;
public void printDefault(){
System.out.println("boolean "+b);
System.out.println("char "+c);
System.out.println("byte "+by);
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("reference "+reference);
}
public static void main(String[] args){
InitDefault id=new InitDefault();
id.printDefault();
}
}
<span style="color:#ff9966;">输出</span>:
boolean false
char
byte 0
short 0
int 0
long 0
float 0.0
double 0.0
reference null
尽管这些变量没有赋值,但是它们确实有初值(char值为0,所以显示空白),boolean类型数据默认初始值为false,其他基本数据类型都为0。而引用变量未赋值,它的初始值为null。(注意:这里的变量时指成员变量,即类变量。如果是局部变量,这没有初始值,必须人为的赋值。)
void f(){
int i;
i++;//错误
}
编译时,上面的方法会报错,告诉你i可能未初始化。局部变量使用前必须赋值。
2 指定初始化
为变量赋初值:(1)可以在定义类成员变量的地方为其赋值,同样也可以这样初始化非基本类型的对象。
示例:
public class InitFiled{
boolean b = true;
char ch = 'x';
byte b = 34;
int i = 730;
float f = 8.4f;
InitFiled init =new InitFiled();//初始化对象。
}
(2)可以通过调用某个方法来提供初值。
示例:
public class InitMethod{
int i = f();
int j = h(i);
int f(){ return 98; }
int h(int n){ return n*4; }
}
这个方法也可以带参数,但是这些参数必须是已经初始化了的。如果改成这样写:
public class InitMethod1{
int j = h(i);//这里显示是不对的
int i = f();
int f(){ return 98; }
int h(int n){ return n*4 ;}
}
显然,上述程序中由于初始化的顺序,变量i并没有初始化呢,所以会有问题。
3 初始化顺序
类的内部,变量定义的先后顺序决定了初始化的顺序,即使变量定义散布于方法定义之间,它们仍旧会在任何方法(包括构造器)被调用之前得到初始化。
示例:
class Window{
Window(int m){ System.out.println("Window(" +m+ ")";}
}
class House{
Window w1 =new Window(1);//构造器前面
House(){
//显示在构造器中
System.out.println("House()");
w3 = new Window(33);
}
Window w2 = new Window(2);//构造器后
void f(){System.out.println("f()";)
Window w3 = new Window(3);
}
public class OrderInit{
Public static void main(String[ ] args){
House h = new House();
h.f();
}
}
输出:
Window(1)
Window(2)
Window(3)
House()
Window(33)
f()
在House类中,故意把几个Window对象的定义散布到各处,但依旧是在调用构造器或其他方法之前得到初始化。
4 静态数据初始化
static关键字不能应用于局部变量,只能作用于域。无论创建多少个对象,静态数据都只占一份存储区域。如果一个字段是静态的基本类型,且没有对它进行初始化,它会获得基本类型的标准初值;如果是一个对象引用,它的默认初始值就是null。在java编程思想中的一个例子:
class Bowl{
Bowl(int m){
System.out.println("Bowl(" + m + “)”);
}
void f1(int m){
System.out.println("f1(" + m +")");
}
}
class Table{
static Bowl bowl1 = new Bowl(1);
Table(){
System.out.println("Table()");
bowl2.f1(1);
}
void f2(int m){
System.out.println("f2(" + m +")");
}
static Bowl bowl2 =new Bowl(2);
}
class Cupboard{
Bowl bowl3 = new Bowl(3);
static Bowl bowl4 = new Bowl(4);
Cupboard(){
System.out.println("Cupboard()");
bowl4.f1(2);
}
void f3(int m){
System.out.println("f3(" + m +")");
}
static Bowl bowl5 =new Bowl(5);
}
public class StaticInit{
public static void main(String[] args){
System.out.println("Creating new Cupboard() in main");
new Cupboard();
System.out.println("Creating new Cupboard() in main");
new Cupboard();
table.f2(1);
cupboard.f3(1);
}
static Table table = new Table();
static Cupboard cupboard = new Cupboard();
}
输出:
Bowl(1)
Bowl(2)
Table()
f1(1)
Bowl(4)
Bowl(5)
Bowl(3)
Cupboard()
f1(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f1(2)
Creating new Cupboard() in main
Bowl(3)
Cupboard()
f1(2)
f2(1)
f3(1)
我们先看一下程序执行流程:
首先是StaticInit类中,(1)先执行static Table table = new Table();原因是静态变量优先于任何方法前执行。创建Table对象引用时先创建bowl1,bowl2。然后调用构造器Table(),构造器中bowl2.f1(1);是因为已经初始化了bowl2对象,所以没有问题。
(2)然后运行static Cupboard cupboard = new Cupboard();有输出可以看出先初始化静态变量bowl4、bowl5,然后是成员变量bowl3,接着才会执行构造器Cupobard()。
(3)下一步执行main()方法,并没有输出Bowl(4) Bowl(5),只输出了Bowl(3),原因是静态初始化只有在必要时刻才会进行,如果不创建Cupboard()对象,也不引用Cupboard().bowl4或Cupboard().bowl5,那么静态的bowl4 bowl5永远不会创建。只有在第一个Cupboard对象创建或第一次访问静态数据的时候,它们才会被初始化。此后静态数据不会再初始化。
未完待续。。。。。。见下一章