java中的static修饰词一直是个貌似很简单但是很容易出错的地方,今天特来总结一下,有什么不对的地方,还望指正
static修饰的变量和方法称为类成员,何为类成员,就是可以直接通过类名去访问的(一般的方法和变量都要用过类的对象去访问的);它们从程序开始到程序结束一直都存在,跟C中的全局变量有点像(java中没有全局变量这一说的),一改全改;static成员是在类被加载时首先被执行的,在整个程序的生命周期中也只会被执行一次,java中最常见的main方法用static修饰也正是这个原因。废话不多说,用实例来说明问题:
代码1:
public class Test{
int a;
public static void main(String[] args){
System.out.println(a);
}
}
结果:无法从静态上下文中引用非静态 变量 a,静态方法只能访问静态变量;
代码2:
public class Test{
public static void main(String[] args){
System.out.println(fun());
}
public int fun(){
int a=0;
return a;
}
}
结果:无法从静态上下文中引用非静态 方法 fun(),静态方法只能访问静态的方法
代码3:
public class Test{
static int a;
public static void main(String[] args){
System.out.println(a);
}
}
结果:输出0,从这可以知道,static变量不初始化的话,其默认值是0;
代码4:
public class Test{
static int a;
public static void main(String[] args){
System.out.println(new Test().a);
System.out.println(Test.a);
}
}
结果:输出两个0,static变量可以通过类名和对象名去访问,需要指出的是,在实例化一个包含static成员的类时,static变量并没有被拷贝到对象中去,而是所有的对象都共用类中的static成员。
代码5:
public class Test{
Test test = new Test(){
int a=0;
};
public static void main(String[] args){
System.out.println(a);
}
}
结果:找不到符号a,不能在static方法中访问实例(对象)中方的成员,原因很简单,static方法会在实例化一个对象之前执行。
代码6:
public class Test{
static int a;
public static void main(String[] args){
System.out.println(this.a);
}
}
结果:无法从静态上下文中引用风非静态变量this,这是一个经常容易犯的错误,this表示的是当前的类实例(对象)的引用,在静态方法和静态代码块中是不能使用this的,因为static修饰的类成员在实例化之前就可以使用了,而this只能在类已经实例化之后才能使用(super同理)。
代码7:
public class Test{
static int a;
public static void main(String[] args){
Son son = new Son(){
System.out.println(a);
};
}
}
结果:错误:需要<标识符>,错误的原因是static成员不能被它所在的类实例所访问
代码8:
public class Test{
public static void main(String[] args){
System.out.println(fun());
}
public static int fun(){
return Son.a;
}
}
static class Son extends Test{ public int a=0; }
结果:此处不允许使用修饰符static,只有内部类才能使用static修饰符。
代码9:
public class Test{
public static void main(String[] args){
System.out.println(fun());
}
public static int fun(){
return Son.a;
}
static class Son{
public int a=0;
}
}
结果:无法从静态上下文中引用非静态变量a,表明a是非静态的,所以static类的成员不一定是static的。
代码10:
class Test{
public Test(){
System.out.print("1");
}
static{
System.out.print("2");
}
{
System.out.print("3");
}
}
public class Son extends Test{
public Son(){
System.out.print("4");
}
static{
System.out.print("5");
}
{
System.out.print("6");
}
public static void main(String[] args){
new Son();
}
}
结果:253164,
表明执行顺序依次为:父类静态块,子类静态块,父类块,父类构造函数,子类块,子类构造函数,这一点也能解释为什么代码5会出错,静态方法会在构造函数之前执行。
<pre code_snippet_id="119789" snippet_file_name="blog_20131219_4_5614178">