static通常无需要本类创建对象就可以使用,直接通过类名来点这个变量或方法。
申明static的限制:
1.只能调用static申明的变量或方法
2.非static申明的变量或方法不能访问
3.不能引用this或super
class c (){
private static int a = 2;
}
main(){
c.a;
}
static静态变量 --共享一块储存区
public class T{
static int i=1;
static void runs(){
i++;
}
main(){
T t1,t2;
system,out.printer(t1.i+","+t2.i);
t1.runs();
system.out.printer(t1.i+","+t2.i);
}
}
输出的是: 1, 1
2,2
可见它调用t1的runs方法,但是在t2中的变量i也取得是那个值
静态块:
public class Value3 {
static int c = 0;
Value3(){
c = 15;
}
Value3(int i){
c = i;
}
static void inc(){
c++;
}
}
public class Count {
public static void prt(String s){
System.out.println(s);
}
Value3 v = new Value3(10);
static Value3 v1,v2;
static{//此即为static块
System.out.println("v1.c="+v1.c+" v2.c="+v2.c);
v1 = new Value3(27);
System.out.println("v1.c="+v1.c+" v2.c="+v2.c);
v2 = new Value3(15);
System.out.println("v1.c="+v1.c +" v2.c="+v2.c);
}
public static void main(String[] args) {
Count ct =new Count();
System.out.println("ct.c="+ct.v.c);
System.out.println("v1.c="+v1.c + " v2.c="+v2.c);
v1.inc();
System.out.println("v1.c="+v1.c + " v2.c="+v2.c);
System.out.println("ct.c="+ct.v.c);
}
}
在mian方法输出的是:
v1.c=0 v2.c=0;
v1.c=27 v2.c=27;
v1.c=15 v2.c= 15 //static块会先运行!!!!
ct.c=10
v1.c=10 v2.c=10
v1.c=11 v2.c=11
ct.c=11
首先它在程序中先运行加载static块,所以在创建这个ct对象时,Count这个类会先执行一次static,所以会先得到结果v1.c=0 v2.c=0; 和v1.c=27 v2.c=27以及 v1.c=15 v2.c=15 之后才会运行ct.c的值
静态类
通常普通类不允许申明为静态的,都是通过内部类来实现,这时这个静态类才可以做为一个普通类来使用,而不需要实例化一个外部类
public class StaticCls {
public static void main(String[] args) {
OuterCls.InnerCls oi = new OuterCls.InnerCls();
}
}
class OuterCls {
public static class InnerCls {
InnerCls() {
System.out.println("InnerCls");
}
}
}
结果为:InnerCls
static修饰的变量叫静态变量或类变量,而不被static修饰的变量叫做实例变量静态变量在类加载时,jvm只为静态分配一次内存,它在内存中只有一个拷贝(节省内存),可通过类名直接点(访问)
实例变量是在每创建一个实例,就会为它分配一次内存,实例变量在内存中会有多个,但是因为它们在栈中的引用地址不一样,它们相互互不影响。
static方法可以通过类名直接来使用,任何的实例都可以用来调用。因此静态方法不能用super和this关键字,因此static不能访问实例变量和方法(就是非static方法和变量)
因为static独立于任何的实例。因此static必须要被实现!