1 静态代码块
下面介绍一种不是很常见的静态修饰符的使用方法。当我们需要一个类,这个类的构造函数是私有的,那么这个类之外其他程序就不能够创建这个类的对象。那么如何初始化这个类呢?
为了解决这个问题,我们可以使用前文中的静态成员变量或者静态方法来初始化类。在类的加载过程中,静态成员变量和静态方法同时也就加载完成了。除了上面的两种方法还有一种更加简单的方法,就是在类中使用静态代码块。静态代码块不是一个方法,它的写法很简单,如下:
public class Car { privateCar() { } static{ Stringcolor="green"; System.out.println("汽车的颜色是:"+color); System.out.println("汽车停下来了"); } publicstatic void main(String[] args) { } }
运行结果如下:
汽车的颜色是:green
汽车停下来了。
这说明在类加载过程中就同时加载了静态代码块中的程序。那么静态代码块中能够写那些内容呢?我们以下面代码为例说明:
public class Car { privateCar() { } Stringcolor="green"; staticString myNewColor="black"; static{ StringmyColor="white"; newCar().show(); stop(); System.out.println("我的车的颜色是:"+myColor); System.out.println("我的车的新颜色是:"+myNewColor); } staticvoid stop(){ System.out.println("汽车停下来了"); } voidshow() { System.out.println("汽车的颜色是:"+this.color); } public staticvoid main(String[] args) { } }
运行结果如下:
汽车的颜色是:green
汽车停下来了。
我的车颜色是:white
我的车的新颜色是:black
从代码中可以得出以下结论:
1、只能直接调用静态方法,而不能直接调用非静态方法;
2、如果需要调用非静态方法同样需要构建对象后才能调用非静态方法;
3、在代码块中声明的变量是局部变量,所以只能声明一般变量而不能声明静态成员变量。
4、代码块中可以直接访问静态成员变量。
通过上述代码,我们发现静态代码块还是功能强大的,能够在不构建对象的情况下,初始化类,解决我们上面提到的需求。
2 静态内部类
如果在一个类中再定义一个类,就将在类中再定义的那个类称为内部类。虽然类不能使用静态修饰符,但是内部类却是可以使用静态修饰符的一个特例。
2.1 定义静态内部类
当我们在定义一个内部类的时候,在内部类的前面增加了静态修饰符static,那么这个类就称为静态内部类。如下代码所示,CarWindow类就是静态内部类,CarDoor类就是非静态内部类。
public class Car { publicstatic class CarWindow{ Public void show(){ System.out.println("车玻璃的颜色是黑色。"); } } Publicclass CarDoor{ Public void show(){ System.out.println("车门的颜色是白色。"); } } publicstatic void main(String[] args) { Car.CarDoorcarDoor=new Car().new CarDoor(); carDoor.show(); } }
要访问非静态类中的show()方法,需要定义对象,然后再通过对象调用show()方法。由于存在外部类和内部类两个类,所以在创建对象的时候,先要创建外部类对象,然后通过外部类对象创建内部类对象。在main()方法中,通过“Car.CarDoor carDoor=new Car().new CarDoor();”语句创建了carDoor对象,然后通过carDoor对象调用show()方法。
运行结果为:
车门的颜色是白色的。
要访问静态内部类与访问非静态内部类略有不同,主要包括访问静态内部类中的非静态成员和静态内部类中的静态成员。下面将分开介绍。
2.2 访问静态内部类中的非静态成员
在静态内部类CarWindow中定义个一个非静态方法show(),如果需要访问这个方法,我们先需要访问外部类Car。不过与访问非静态内部类不同的是,访问静态内部类时,由于静态内部类的加载与外部类的加载同时,所以不需要创建外部类对象,而是直接创建内部类对象,在使用内部类对象访问非静态方法show()。
要访问CarWindow中定义的非静态方法show(),需要修改main()方法如下:
public staticvoid main(String[] args) { Car.CarDoorcarDoor=new Car().new CarDoor(); carDoor.show(); Car.CarWindowcarWindow=new Car.CarWindow(); window.show(); }
运行结果为:
车门的颜色是白色的。
车玻璃的颜色是黑色的。
2.3 访问静态内部类中的静态成员
当在静态内部类中存在静态成员,例如静态成员变量或静态方法,这时访问静态内部类的静态成员就更加简单。因为静态内部类随着外部类的加载而加载,而内部类中的静态成员随着内部类加载而加载。
也就是说当外部类加载完成后,静态内部类以及静态成员也就同时完成了加载。所以不需要对象就可以实现静态内部类中的静态成员的访问,直接使用类名就可以完成访问。
将上面代码中静态内部类CarWindow的show()方法改为静态方法,那么在main()方法中做如下修改:
public staticvoid main(String[] args) { Car.CarWindow.showCarWindow(); }
运行结果为:
车玻璃的颜色是黑色的。
虽然访问静态内部类的静态方法用起来很简单,但是当定义为静态时,就存在了局限性。在前文中提到过静态方法只能访问静态成员,所以不是什么情况都适合使用静态修饰符的。