- 从内存角度来分析static关键字
对于这个问题,我们只需简单知道三件事,栈、堆和方法区
栈区:存放对象的引用或者数组的引用
堆区:存放具体的对象或者数组
方法区:存放方法和共享变量(static修饰) - static修饰类的属性
如果一个属性没有被static修饰,那么当这个类的一个对象被new出来的时候,这个变量是跟随这个对象放在堆区的。当这个变量被static修饰,那么它会随着类的加载而被初始化到方法区。因此,我们不仅可以通过一个对象来访问该属性,还可以直接通过类名访问。 - static修饰方法
对于一个类来说,它的方法本来就存在于方法区,即使被static修饰了,它依然在方法区。如果某个方法被static修饰了,那么我们可以直接通过类名来调用方法,当然也可以通过对象来访问该方法。
需要注意的是,被static修饰的方法是不能调用非static修饰的方法的,因为非static修饰的方法要通过对象来调用。 - static修饰代码块
class Foo{
//代码块,在创建对象的时候执行,使用很少,和构造器差不多
{
System.out.println("创建对象了!");
}
//静态代码块,在类加载期间执行,用于加载配置文件或者其他信息等
static{
System.out.println("类加载了!");
}
public Foo(){
System.out.println("调用了构造器!");
}
}
当类加载的时候,静态代码块就会执行,当new一个对象的时候,非静态代码块会执行。
- static修饰类
普通类是不能被static修饰的,只有内部类才能被static修饰。一旦一个内部类被static修饰,那么这个静态内部类对象可以脱离外部类对象而存在,否则的话,要绑定一个内部类对象才可以。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Apple apple = new Apple();
Apple.Seed seed = apple.new Seed();//绑定一个外部类对象
Apple.Skin skin = new Apple.Skin();
}
static class Fruit{
public Fruit(){
Log.d("MainActivity","create Fruit");
}
}
static class Apple extends Fruit{
public Apple(){
super();
Log.d("MainActivity","Apple create");
}
public static class Skin{
}
public class Seed{
public Seed(){
}
}
}
}
关于static我们就说这么多吧。