所有变量在使用前都要得到恰当的初始化!对于方法的局部变量,java以编译时错误的形式来贯彻这种保证,因此,如果写成:
void f() {
int i;
i++;
}
这样就会得到错误信息了,在定义i的时候没有初始化。
但要是类的数据成员(字段)是基本类型,那情况也就不同啦。因为类的每个基本类型数据成员保证都会有一个初始值。
package CSDN;
public class Initialvalues {
boolean a;
char b;
int c;
double d;
Initialvalues reference;
void printInitialvalues() {
System.out.println("Data type Initialvalues");
System.out.println("boolean "+a);
System.out.println("char ["+b+"]");
System.out.println("int "+c);
System.out.println("double "+d);
System.out.println("reference "+reference);
}
public static void main(String[] args) {
Initialvalues i = new Initialvalues();
i.printInitialvalues();
/*or
* new Initialvalues().printInitialvalues();
*/
}
}
/*
Data type Initialvalues
boolean false
char [ ]
int 0
double 0.0
reference null
*///
由此可见尽管数据成员的初始值没有给出,但是他们有初始值(char值为0,所以显示为空白)。
我在这里也定义了一个对象的引用,也就是reference,但是我没有初始化它,结果是null,可见他也被赋予了初始值。
接下来介绍指定初始化
比较直接的方法就是在定义类成员变量的地方就为其赋值(C++可不能这样哈,学C++的同志们开心吗),代码走起:
public class Initialvalues1 {
boolean bool = true;
char ch = 'x';//这里只能是一个字符
byte b = 47;
short s = 0xff;
int i = 999;
long lng = 1;
float f = 3.14f;
double d = 3.1415926;
}
当然,也能用同样的方法初始化非基本类型的对象。比如像下方代码,如果apple是一个类,那么就可以创建一个对象并初始化它:
class Apple {
}
public class Initialvalues1 {
Apple d = new Apple();
}
甚至可以通过调用某个方法来提供初始值
public class Initialvalues1 {
int i = f();
int f() {
return 'a';
}
/*or
* int i = f();
* int j=g(i);
* int f(){return 1;}
* int g(int n){return n-1;}
*/
/*但是不能这样
* int j=g(i);
* int i = f();
* int f(){return 1;}
* int g(int n){return n-1;}
*/
}
可以用构造器来初始化,在运行时刻,可以调用方法或执行某些动作来确定初值。但是,我们无法阻止自动初始化的进行,他将在构造器被调用之前发生。
class Counter {
int i;
//Counter(){
// i = 7;
//}
}
public class Initialvalues {
public static void main(String[] args) {
Counter a = new Counter();
System.out.println(a.i);
}
}
/*output1:
0
output2:
7
*///
i首先被置0,然后变成7;由此可知,使用构造器的时候,不一定要在构造器的某个地方对元素初始化。
初始化顺序:
在类的内部,变量定义的先后顺序决定了初始化的顺序。即使变量定义散布于方法定义之间,它们仍旧会在任何方法(包括构造器)被调用之前得到初始化。
class Window{
Window(int q)
{
System.out.println("Window("+q+")");
}
}
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 Initialvalues {
public static void main(String[] args) {
House t = new House();
t.f();
}
}
/*output:
Window(1)
Window(2)
Window(3)
House()
Window(33)
f()
*///
在House类中,故意把几个Window对象的定义散布到各处。但是从结果可以看出,尽管位置顺序不同,但前三个都是在调用方法之前算出的,它们三个之间又是按照先后定义的顺序排序的。W3这个引用被初始化了两次,一次在调用构造器之前,一次是在调用期间。因此,第一次引用的对象将被丢弃,并作为垃圾回收。
class Bowl{
Bowl(int marker){
System.out.println("bowl "+marker);
}
void f1(int marker) {
System.out.println("f1 "+marker);
}
}
class table{
static Bowl bowl1 = new Bowl(1);
table(){
System.out.println("table()");
bowl2.f1(1);
}
void f2(int marker) {
System.out.println("f2 "+marker);
}
static Bowl bowl2 = new Bowl(2);
}
class cupboard{
Bowl b3 = new Bowl(3);
static Bowl bowl4 = new Bowl(4);
cupboard(){
System.out.println("cupboard()");
bowl4.f1(2);
}
void f3(int marker) {
System.out.println("f3 "+marker);
}
static Bowl bowl5 = new Bowl(5);
}
public class Initialvalues {
public static void main(String[] args) {
System.out.println("Creating new cupboard() in mian");
new cupboard();
System.out.println("Creating new cupboard() in mian");
new cupboard();
a.f2(1);
s.f3(2);
}
static table a = new table();
static cupboard s = new cupboard();
}
/*output:
bowl 1
bowl 2
table()
f1 1
bowl 4
bowl 5
bowl 3
cupboard()
f1 2
Creating new cupboard() in mian
bowl 3
cupboard()
f1 2
Creating new cupboard() in mian
bowl 3
cupboard()
f1 2
f2 1
f3 2
*///
静态数据的初始化