关键字static是一个修饰符,其可以修饰一下几种:
1,属性;2,方法;3,语句块;4,内部类。
static代表的是类相关,static修饰的东西,所有的对象共享(共享同一块的内存区域)。其修饰的一些东西放在了static池中(堆内存中一块新的内存区域)。池虽然是堆里的一块区域,但是同堆的最大的不同就是:常驻内存,反复利用。、
常见的池有:数据库连接池,String常量池,线程池,static池。
static池的作用:
static的属性和方法可以用 对象. 这种方式调用,但做好使用 类名. 调用。(用对象. 调用static的属性,可读性差,因为,非static的属性也可以用对象.的方式调用,这样我们不容易看出调用的属性是static的还是非static的。还有就是,类名.调用,不需要创建对象,很明显能够节省内存的开销。)
public class TestStatic {
static int i1 =1;
static{ //在类加载的时候执行,先于main方法执行,即类加载是先于main方法的
System.out.println("static block");
}
{ //语句块,在构造对象时执行,在执行构造前执行
System.out.println("block");
}
public TestStatic(){
System.out.println("TS");
}
public static void main(String[] args) {
System.out.println("begin");
TestStatic ts;
System.out.println("end");
ts = new TestStatic();
}
}
public class TestS {
public static void main(String[] args) {
System.out.println("begin");
TestStatic ts;
System.out.println(TestStatic.i1);
System.out.println("end");
ts = new TestStatic();
}
}
static的方法不能访问非static的属性。静态的东西存在比非静态的东西早,这也就是为什么能用不创建对象,却能用类名.调用的原因。非static的属性和方法在创建对象的时候才能够在内存中申请空间,而static的东西在用的时候,可能没有对象。也就是说,类名.(static属性或者方法)的时候,内存中可能没有对象。所以跟对象相关的一些东西都不能在static的部分出现。还有就是static的方法在重写的时候,必须使用static的方法去覆盖(即重写后的方法也必须是static的)。
既然static的修饰的东西(属性,方法,语句块,内部类)比创建对象的时候还早,那他们究竟在什么时候到到内存中呢?可以这样说,通过上面那段代码,可以告诉我们,static修饰的东西都是在类加载的时候进入内存中的。虚拟机在加载类的时候,需要遵循一个原则:Just in time。即在用的时候加载。这有使用静态语句快才能看出来。
语句块:凡是在类里边写一大括号,在括号里边直接写语句,都算作是语句快。而静态语句快则是在语句块前边加static就可以了。通过上边的代码可以告诉我们:
结论1:语句块在构造对象的时候执行,在执行构造前执行。
结论2:静态的语句块,先与main方法执行,即在类加载的时候执行。
结论3:申明一个变量时,类不会被加载(符合类加载的原则Just in time)。
结论4:构造对象的时候,会加载类。
结论5:类名.的时候也会加载类。