注意:非静态方法既可以访问静态数据成员 又可以访问非静态数据成员,而静态方法只能访问静态数据成员;
非静态方法既可以访问静态方法又可以访问非静态方法,而静态方法只能访问静态数据方法。
原因:因为静态方法和静态数据成员会随着类的定义而被分配和装载入内存中,而非静态方法和非静态数据成员只有在类的对象创建时在对象的内存中才有这个方法的代码段。
引用静态方法时,可以用类名.方法名或者对象名.方法名的形式。
对以上描述进行验证的代码示例(小树亲测):
import java.util.*;
public class TestStatic {
public static void main(String[]args){
System.out.println(S.getStatic());//使用类名加前缀访问静态方法
S s=new S();
System.out.println(s.getStatic());//使用实例化对象名访问静态方法
System.out.println(s.get());
}
public static class S
{
private static int a;
private int t=0;
//静态初始器:由static和{}组成,只在类装载的时候(第一次使用类的时候)执行一次,往往用来初始化静态变量。
static{
a=10;
}
//静态方法只能访问静态数据成员
public static int getStatic()
{
return a;
}
public int getT()
{
return t;
}
//非静态方法可以访问静态方法和非静态方法
public int get()
{
getT();
getStatic();
t=a;//非静态方法可以访问非静态数据成员和静态数据成员
return t;
}
}
}
总结:
(1)static修饰的静态方法会随着类的定义而被分配和装载入内存中,编译器只为整个类创建了一个静态变量的副本,也就是只分配一个内存空间,虽然可能有多个实例,但这些实例共享该内存,特别值得注意的是,任何一个对象对静态数据成员的修改,都会影响其它对象。
(2)静态不能引用非静态这一特性,是由于静态的会随着类的定义而被分配和装载入内存中这一关键点决定的;如果静态引用了非静态的,根本无法从内存中找到非静态的代码段,势必会出错,这种做法是Java虚拟机决不允许的。