static关键字
1. static修饰成员变量
static修饰成员变量:如果一个数据要被所有对象共享使用的时候 就可以用static修饰该成员变量
访问方式
1 使用对象进行访问 格式 对象.静态属性名
2 使用类名进行访问 格式 类名.静态属性名
class Stu{
String name;
static String country="中国";
}
public class Demo {
public static void main(String[] args) {
Stu s=new Stu();
System.out.println(Stu.country);
System.out.println(s.country);
}
}
注意
1 静态的成员变量可以用类名或者对象的形式进行访问
2 非静态成员变量只能用对象的形式进行访问
2 . static修饰成员函数
静态函数的访问方式
方式1 使用对象.函数名();
方式2 使用类名.函数名();
注意
1 静态函数可以直接访问静态的成员 但是不能直接访问非静态的成员
2 非静态函数可以直接访问静态以及非静态的成员
3 非静态函数只能使用对象调用 不能使用类名调用
4 静态函数不能出现this和super关键字
class Stu{
{
//构造代码块在创建对象的时候被执行
System.out.println("构造代码块被执行了");
}
static {
//所属类的字节码被加载到内存的时候就执行了
System.out.println("静态代码块被执行了");
}
public static void fun() {
System.out.println("hhh");
}
}
public class Demo {
public static void main(String[] args) {
//并没有创建对象 使用类名调用
Stu.fun();
}
}
上述例子说明静态成员优先于对象存在 下面来看一个具体分析
class Stu{
String name;
static String country="中国";
}
public class Demo {
public static void main(String[] args) {
Stu s1=new Stu();
}
}
分析
首先 Demo.class 加载到方法区中 当执行main方法时,发现要加载Stu类 于是Stu也被加载到了方法区中 此时Stu中的静态成员变量被放到了静态数据共享区 再然后栈内存中创建了s1对象,指向了堆中的空间 由此可见静态数据在类文件加载的时候就进入了内存而非静态数据在创建对象的时候才存在可以得到一个结论 静态数据优先于对象存在
总结
我们再来看一下刚才的4条注意和他们的原因
1 静态函数可以直接访问静态的成员 但是不能直接访问非静态的成员
静态函数加载到内存中的时候 对象可能还没有在内存中 非静态数据也就不存在
2 非静态函数可以直接访问静态以及非静态的成员
非静态函数存在的时候 静态数据早就已经加载到了内存中
3 非静态函数只能使用对象调用 不能使用类名调用
4 静态函数不能出现this和super关键字
静态数据在类文件加载的时候就进入内存 但此时可能还没有对象存在 而this关键字代表该函数的调用者对象 必须依赖对象的存在
3. 静态成员与非静态成员区别
1 静态成员在方法区中维护一份数据
非静态成员在每个对象中都维护一份数据
2 非静态成员只能使用对象进行访问
静态成员可以使用对象或者类名的形式进行访问
3 非静态成员存储在堆内存中
静态成员存储在方法区中
4 非静态成员随着对象的创建而创建 随着对象消失而消失
静态数据随着类文件(字节码)的加载而存在 随着类文件的消失而消失
5 非静态数据描述一类事物的属性
静态数据提供一个共享数据供对象使用