static解析

今天在某个代码里看到静态域的使用,出于学习的目的,专门对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方法,输出结果:

[quote]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[/quote]

要是改变初始化与域的位置,输出结果也会有相应改变,同样静态(或非静态)的初始化和域,基本按照先后顺序执行。

结论是:

1)静态元素(变量、方法、域、内部类)不能直接调用非静态元素 ,需要对非静态元素所属类实例化,特别是调用非静态内部类时,需要对其外部类实例化,然后获取非静态内部类的实例对象。

2)不管位置如何,静态初始化 / 域先于非静态初始化 / 域,父类的初始化 / 域先于子类的初始化 / 域,变量的初始化以及域先于构造方法执行。即:
a) 先初始化 / 域,后构造方法;
b) 先“静态”后“非静态”;
c) 先父后子。
其他静态 / 非静态方法均需调用才能执行

这里请注意次序排列的先后顺序,比如静态非静态的区分先于父子类的区分,即子类的静态初始化比父类的非静态初始化优先的。

3)静态方法在第一次被执行时,会先执行静态的初始化和域,如所属类的main方法,构造方法虽没有static标示符,但也可以认为是静态方法。而在构造方法执行(即实例化)时,除了执行静态初始化和域,接着又会执行非静态的初始化和域。

当然非静态在每次实例化都会执行一次。


关于域,那是不归于方法封装的执行代码,即它是可以主动执行(静态在定义时,非静态在实例化时进行)的,而不必通过方法调用,应该有点类似C吧。

4)域中可以定义变量和类,但不能是静态变量和静态类(因为不需要共享),并且变量和类都只是域内部使用,因此不需要public/protected/private标识符。

[b]补充:[/b] 谢谢各位的支持,另外应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的测试结果:

[quote]外部类测试:
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[/quote]

结论是:
5)静态类首先是内部类,静态类当中可以定义静态元素和非静态元素(包括内部类、变量、方法、域),而非静态内部类只能定义非静态元素。静态类可以直接调用外部类的静态元素,非静态内部类可以直接调用外部类的静态和非静态元素。

6)外部类在执行变量初始化和域(包括静态和非静态)时,不会涉及其内部类的变量初始化和域。相对的,内部类(包括静态类和非静态内部类)在执行自己的变量初始化和域时,也不会执行静态类所属外部类的变量初始化和域。

当然,非静态内部类必须通过其外部类的实例对象来调用,因此会先执行外部类的构造方法,于是该发生的还是会发生。


写的很乱,这是我的第二篇博文,欢迎各位拍砖。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值