此static非彼static
Dec5
(以下内容是对一个简单但容易混淆的基础概念的备注,适用于写Java的C#er。请各位Javaer,达人,牛人,机器人以及太空人自动忽视,否则看后被雷后果自负)
对于C#er来说静态类再熟悉不过了,然而在Java中由static声明的class绝非C#中的static class,2者的意思可以说是差个十万八千里远,以致于我在google上搜索“Java 静态类”的前几条结果竟然都没有将这个概念说清楚,而且还有一摩尔多的帖子将Java中的static class和C#的static class混为一潭。(真不明白那几个大大是怎么学习的啊~~~,其实这个概念在《Core Java》中解释的粉清楚,而且只用了1页多一点,看来和我一样的剑宗派还真不少啊)
C#中的静态类就是只包含静态方法和静态字段不能被实例化的类,这个不用多说。但是Java中根本就没有这种类,要得到类似的效果只能使用单件模式模拟。那Java中的static class是什么意思呢?Java中的static class只能申明在一个类的内部,也就是说只能是一个嵌套类或者叫做内部类,并且这个内部类并不是C#中的那种不能实例化的类,这种类是可以实例化的,那么它表示什么意思呢?例如下面的Java代码:
public class OuterClass {
public int Field1;
private class InnerClass{
public void Foo(){
int myField = Field1;
//……
}
}
public void OuterFoo(){
InnerClass innerObj = new InnerClass();
innerObj.Foo();
}
}
这段代码中的InnerClass不是static的,那么这会发生什么呢?注意到InnerClass中的Foo方法使用到了OuterClass中的Field1!也就是说当我们在OuterClass的OuterFoo方法中构造InnerClass的实例时,OuterClass当前实例的this指针以某种方式被传递到了构造出的InnerClass实例中,这样在InnerClass的Foo方法中才可能访问到OuterClass中的Field1,实际上这是Java编译器干的事情,Java编译器编译的OuterFoo方法实际上是:
public void OuterFoo(){
InnerClass innerObj = new InnerClass(this);
innerObj.Foo();
}
再来说static内部类就清楚了,如果InnerClass是static的,那么在构造InnerClass的实例时(注意,即使是static的内部类也是可以构造实例的,不要和C#混为一谈)编译器就不会干上面那件事情,所以InnerClass中的方法就没有办法使用OuterClass中的字段了。至于为什么这个关键字会是对C#er来说很混淆的static?想想如果上面的OuterFoo方法是一个静态方法,那么编译器就根本没有办法在这个方法内使用this指针,所以静态方法中构造和使用的内部类就必须声明为static的。
搞清楚这个问题,各位C#er无论是在写Java或者看开源的Java代码的时候遇到里面的static,就不会有抓耳挠腮想自杀的感觉了~~~ 最后ps,Java和C#虽然非常类似,但是实际上还是有很多概念相当的混淆,对于要经常看开源Java代码的C#er来说,搞清楚这些概念还是很有必要的。