一、静态成员先于实例成员存在
类被加载到内存时,静态变量分配内存空间,静态方法分配入口地址
只有创建对象之后,实例变量分配内存空间,实例方法分配入口地址
当再创建对象时,实例方法不再分配入口地址,方法入口地址被所有对象共享
class A {static {System.out.println("class A static...");}
}public class B {public static void main(String[] args) { A a = new A(); // 创建对象}static {System.out.println("class B static...");}
}
二、推荐使用类名访问静态成员
静态成员与类相关联,可以通过类名访问,也可以通过对象访问
实例成员与相应的对象关联,只能通过对象访问,不能通过类名访问
class A {static int numberA = 100;
}class B {static int numberB = 200;public static void main(String[] args) {A a = new A();System.out.println(a.numberA);B b = new B();System.out.println(b.numberB);}/*** 编译之后的字节码文件 B.class* 使用对象访问静态成员,javac编译成“类名.静态成员”* class B {* static int numberB = 200;** B() { }** public static void main(String[] args) {* A a = new A();* System.out.println(A.numberA); // javac编译成“类名.静态成员”* B b = new B();* System.out.println(numberB); // 本类中访问静态成员,省略类名* }* }*/
}
三、对象共享静态变量,对象独占实例变量
分配给不同对象的实例变量占有不同的内存空间,改变其中一个对象的实例变量不会影响其他对象的实例变量
分配给不同对象的类变量占有相同的一处内存,改变其中一个对象的这个类变量会影响其他对象的这个类变量
class B {int n; // 实例变量static int sum = 0; // 静态变量public void setN(int n) {this.n = n;}int getSum() {for (int i = 1; i <= n; i++) {sum += i;}return sum;}
}public class Test {public static void main(String[] args) {B b1 = new B();b1.setN(3);B b2 = new B();b2.setN(5);System.out.println("b1-sum:" + b1.getSum()); // 1+2+3=6System.out.println("b2-sum:" + b2.getSum()); // 6+1+2+3+4+5=21}
}
四、静态不能访问实例,实例可以访问静态
静态方法只能操作静态变量,调用静态方法
实例方法可以操作实例变量、静态变量,调用实例方法、静态方法
class A {private String str; // 实例变量public static int num = 10; // 静态变量public static void method() {// 静态不能【直接】访问实例// 在静态方法中创建对象,用对象访问实例成员new A().str = "hello"; System.out.println("num = " + num);}
}