一、static成员变量
按照是否静态的对类成员变量进行分类可分两种:一种是被static修饰的变量,叫静态变量或类变量;另一种是没有被static修饰的变量,叫实例变量。
两者的区别是:
静态变量属于类,对于静态变量在内存中只有一个复制(节省内存,所有实例都指向同一个内存地址),JVM只为静态分配一次内存,在加载类的过程中完成静态变量的内存分配,可用类名直接访问(方便),当然也可以通过对象来访问(但是这是不推荐的)。
对于实例变量,每创建一个实例,就会为实例变量分配一次内存,实例变量可以在内存中有多个复制,互不影响(灵活)。
所以一般在需要实现以下两个功能时使用静态变量:
在对象之间共享值时
方便访问变量时
public class Man {
private static int i=0;
private int j;
public static void main(String[] args) {
System.out.println(Man.i);
Man man=new Man();
man.i++;
man.j++;
System.out.println(man.i);
System.out.println(man.j);
Man man2=new Man();
System.out.println(man2.j);
System.out.println(man.i);
}
}
运行结果:
0
1
1
0
1
需要注意的是不允许在方法体中定义static。因为:static变量先于方法被初始化
二、static成员方法
①静态方法可以直接通过类名调用,任何的实例也都可以调用,
因此静态方法中不能用this和super关键字,不能直接访问所属类的实例变量和实例方法,只能访问所属类的静态成员变量和成员方法。
因为当static方法被调用时,这个类的对象可能还没有建立,即使已经建立对象,也无法确定调用哪个对象的方法。同理,static方法也不能访问非static类型的变量。
因为static方法独立于任何实例,因此static方法必须被实现,而不能是抽象的abstract。
例如为了方便方法的调用,Java API中的Math类中所有的方法都是静态的,而一般类内部的static方法也是方便其它类对该方法的调用。
静态方法是类内部的一类特殊方法,只有在需要时才将对应的方法声明成静态的,一个类内部的方法一般都是非静态的
③static的一个重要应用单例:https://blog.csdn.net/jiangshangchunjiezi/article/details/74597029
三、static代码块
static代码块也叫静态代码块,是在类中独立于类成员的static语句块,可以有多个,位置可以随便放,它不在任何的方法体内,JVM加载类时会执行这些静态的代码块,如果static代码块有多个,JVM将按照它们在类中出现的先后顺序依次执行它们,每个代码块只会被执行一次。
public class Test5
{
private static int a;
private int b;
static
{
Test5.a=3;
System.out.println(a);
Test5 t=new Test5();
t.f();
t.b=1000;
System.out.println(t.b);
}
static
{
Test5.a=4;
System.out.println(a);
}
public static void main(String[] args)
{// TODO 自动生成方法存根
}
static
{
Test5.a=5;
System.out.println(a);
}
public void f()
{System.out.println("hhahhahah");}}
运行结果:
3
hhahhahah
1000
4
5
四、static内部类
static内部类是指被声明为static的内部类,它可以不依赖于外部类实例对象而被实例化,而通常的内部类需要在外部类实例化后才能被实例化。静态内部类不能与外部类有相同的名字,不能访问外部类的普通成员变量,只能访问外部类的静态成员和静态方法
参考: