锁定老帖子 主题:static解析
精华帖 (2) :: 良好帖 (4) :: 新手帖 (15) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-08-09
Firklaag 写道 请问为什么可以在非静态内部类中定义 比如
static final int i= 0; 这类的属性? 字段定义,和类是不是静态没有关系。 static和非static是生命周期和作用域不同。 |
|
返回顶楼 | |
发表时间:2011-03-02
这里请注意次序排列的先后顺序,比如静态非静态的区分先于父子类的区分,即子类的静态初始化比父类的非静态初始化优先的。
这个有异议,父类的静态初始化应该高于子类的静态初始化,而父类的非静态初始化落后于子类的静态初始化; 补充一点直接用子类调用其中的静态方法 只初始化子类的静态成员而不初始化父类的静态成员(和父类无关); |
|
返回顶楼 | |
发表时间:2011-03-08
ddzero 写道 今天在某个代码里看到静态域的使用,出于学习的目的,专门对static相关的内容(静态类、方法、变量、域,以及非静态的)进行测试
废话不多说,上代码: 主类 StaticTest.java public class StaticTest extends fatherClass{ //初始化时,可以直接调用静态成员,以及同类的非静态成员 //静态变量初始化时不能引用非静态成员 public static int staticVar=new AssistClass().getNum2(); //静态域与静态变量初始化具有相同的优先级 static{ staticVar++; System.out.println("static block"); //域中可以定义变量以及类,不能定义方法,并且只是在域中使用 //不能带有public\protected\private标示符 int var2=3; class NSC2{ int i=2; } // System.out.println(new NSC2().i); //不允许定义静态变量和静态类 //! static int staticVar2; //! static class SC2{} } public int var=new AssistClass().getNum(); public int var2=fun3(); public StaticTest(){ System.out.println("constructor"); } //非静态域与非静态变量初始化具有相同的优先级 { //静态域可以访问所属类的静态 var++; staticVar++; System.out.println("not static block"); } public void fun(){//非静态方法可以直接调用静态和非静态成员 staticVar=1; staticFun(); fun2(); } public void fun2(){ } public int fun3(){ return 3; } public static void staticFun(){ //静态方法不能直接调用非静态成员 //需要:1.实例化 2.改为静态 //! fun2(); System.out.println("sattic method"); } public static int staticFun2(){ System.out.println("static field init"); return 2; } public static int staticFun3(){ System.out.println("not static field init"); return 3; } /** * @param args */ //静态方法在第一次执行时会先执行静态初始化和静态域 //构造方法可以认为是静态方法 //每次实例化都会执行一次非静态初始化和非静态域 public static void main(String[] args) { // TODO Auto-generated method stub // staticFun(); // new StaticTest(); new StaticTest(); // System.out.println(st.var+"&"+st.var2+"&"+staticVar); } //结论:静态成员可以被直接调用,非静态成员则需经实例化(但可以被同类的非静态成员调用) } 辅助类 AssistClass.java public class AssistClass{ int i=1; public int getNum(){ System.out.println("not static field init"); return 4; } public int getNum2(){ System.out.println("static field init"); return 5; } public int getNum3(){ System.out.println("father static field init"); return 5; } public int getNum4(){ System.out.println("father not static field init"); return 5; } public static void main(String[] args){ //静态方法在第一次执行时会先执行静态初始化和静态域 //构造方法可以认为是静态方法 //每次实例化都会执行一次非静态初始化和非静态域 new StaticTest(); new StaticTest(); } } 父类 FatherClass.java public class fatherClass{ //同静态时,父类的变量初始化/域先于子类执行 static int fatherVar=new AssistClass().getNum3(); static{ System.out.println("father static block"); } //同非静态时,父类的变量初始化/域先于子类执行 { System.out.println("father not static block"); } int fatherVar2=new AssistClass().getNum4(); } 关于静态成员与非静态成员之间的调用关系,这里不赘述,因为这是语法问题,各位只要写一写代码就了解了 执行StaticTest类的main方法,输出结果: 引用 father static field init
father static block static field init static block father not static block father not static field init not static field init not static block constructor 要是改变初始化与域的位置,输出结果也会有相应改变,同样静态(或非静态)的初始化和域,基本按照先后顺序执行。 结论是: 1)静态元素(变量、方法、域、内部类)不能直接调用非静态元素 ,需要对非静态元素所属类实例化,特别是调用非静态内部类时,需要对其外部类实例化,然后获取非静态内部类的实例对象。 2)不管位置如何,静态初始化 / 域先于非静态初始化 / 域,父类的初始化 / 域先于子类的初始化 / 域,变量的初始化以及域先于构造方法执行。即: a) 先初始化 / 域,后构造方法; b) 先“静态”后“非静态”; c) 先父后子。 其他静态 / 非静态方法均需调用才能执行 这里请注意次序排列的先后顺序,比如静态非静态的区分先于父子类的区分,即子类的静态初始化比父类的非静态初始化优先的。 3)静态方法在第一次被执行时,会先执行静态的初始化和域,如所属类的main方法,构造方法虽没有static标示符,但也可以认为是静态方法。而在构造方法执行(即实例化)时,除了执行静态初始化和域,接着又会执行非静态的初始化和域。 当然非静态在每次实例化都会执行一次。 关于域,那是不归于方法封装的执行代码,即它是可以主动执行(静态在定义时,非静态在实例化时进行)的,而不必通过方法调用,应该有点类似C吧。 4)域中可以定义变量和类,但不能是静态变量和静态类(因为不需要共享),并且变量和类都只是域内部使用,因此不需要public/protected/private标识符。 补充: 谢谢各位的支持,另外应logic的要求,对静态类进行了测试 请看代码: StaticTest2.java public class StaticTest2 { static int staticVar; int var; static class StaticClass{ //静态类中可以定义静态、非静态的成员、域 //静态类中可以调用外部类的静态成员 public static int S2Var=staticVar; //静态类中需要对外部类实例化,才能调用外部类的非静态类成员 public int NS2Var=new StaticTest().var; static{ System.out.println("static Class > static block"); } { System.out.println("static class > not static block"); } class NS2Class{} static class S2Class{public static int S2var;} public static void staticFun(){ System.out.println("this is static class"); } public void fun(){ System.out.println("this is static class"); } } class NotStaticClass{ //非静态内部类不能定义静态域 //提示错误:Cannot define static initializer in inner type StaticTest2.NotStaticClass //! static { System.out.println("not static Class > static block"); } { System.out.println("not static class > not static block"); } //非静态内部类中不能定义静态变量 //提示错误:The field var cannot be declared static; static fields can only be declared in static or top level types //! static int var; //非静态内部类中不能定义静态方法 //提示错误:The method staticFun cannot be declared static; static methods can only be declared in a static or top level type //! public static void staticFun(){} class NS2Class{} //非静态内部类中不能定义静态类 //提示错误:The member type S2Class cannot be declared static; static types can only be declared in static or top level types //! static class S2Class{} public void fun(){ System.out.println("this is not static class"); } } static{ System.out.println("static block"); } { System.out.println("not static block"); } public NotStaticClass getNSC(){ return new NotStaticClass(); } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub System.out.println("............hua li de fen ge xian.............."); StaticTest2.StaticClass.staticFun(); new StaticClass().fun(); //等同于 // new StaticTest2.StaticClass().fun(); //外部类(即StaticTest2)需经实例化, //设法获取静态内部类的实例(如getNSC()),才能调用非静态内部类的非静态成员 (new StaticTest2()).getNSC().fun(); //! new NotStaticClass().fun(); } } AnnotherTest.java public class AnnotherTest{ public static void main(String[] args) { // TODO Auto-generated method stub System.out.println("外部类测试:"); //外部类初始化时,会执行其静态变量初始化和静态域,但不会涉及其静态类 new StaticTest2(); System.out.println("静态类测试:"); /* * 静态类测试 */ //静态类调用其成员,静态类的外部类不需要经实例化 //静态类调用其静态成员,此时不会执行其外部类(StaticTest2)的静态变量初始化和静态域 StaticTest2.StaticClass.staticFun(); // System.out.println( StaticTest2.StaticClass.S2Class.S2var ); //静态类调用其非静态成员 // new StaticTest2.StaticClass().fun(); System.out.println("非静态内部类测试:"); /* * 非静态内部类测试 */ //StaticTest2.NotStaticClass只能调用class元素 System.out.println(StaticTest2.NotStaticClass.class); //非静态内部类中不能定义静态元素 //外部类(即StaticTest2)需经实例化, //设法获取静态内部类的实例(如getNSC()),才能调用非静态内部类的非静态成员 (new StaticTest2()).getNSC().fun(); //以下代码会编译错误,需先实例化外部类 //! new StaticTest2.NotStaticClass().fun(); } } 重点在AnnotherTest的测试结果: 引用 外部类测试:
static block not static block 静态类测试: static Class > static block this is static class 非静态内部类测试: class defaultPackage.StaticTest2$NotStaticClass not static block not static class > not static block this is not static class 结论是: 5)静态类首先是内部类,静态类当中可以定义静态元素和非静态元素(包括内部类、变量、方法、域),而非静态内部类只能定义非静态元素。静态类可以直接调用外部类的静态元素,非静态内部类可以直接调用外部类的静态和非静态元素。 6)外部类在执行变量初始化和域(包括静态和非静态)时,不会涉及其内部类的变量初始化和域。相对的,内部类(包括静态类和非静态内部类)在执行自己的变量初始化和域时,也不会执行静态类所属外部类的变量初始化和域。 当然,非静态内部类必须通过其外部类的实例对象来调用,因此会先执行外部类的构造方法,于是该发生的还是会发生。 写的很乱,这是我的第二篇博文,欢迎各位拍砖。 |
|
返回顶楼 | |