目录
static关键字:
static关键字:
static作用:
static代码块:
static关键字:
static是一个特殊意义的关键字,被static修饰的变量和方法称为静态变量,静态方法。随着类的加载而加载,它的生命周期和类相同。
static作用:static在Java中主要做内存管理,static修饰的数据在内存中只会存储一份,适合用于做数据共享
1.修饰属性,用于数据共享
static可以用于修饰属性,被static修饰的属性被成为类成员或者静态变量,这个是相对于对象来讲的。
但是为什么static修饰的属性为什么可以用于数据共享呢?我们先看这两段代码:
public class Test4 {
public static void main(String[] args) {
Person p1 = new Person();
p1.age=13;
Person p2 = new Person();
p2.age=14;
System.out.println(p1.age);
System.out.println(p2.age);
}
}
class Person{
String name;
int age;
public void eat(){
System.out.println("吃饭");
}
}
分别创建两个对象,对两个对象的age属性赋值, p1和p2的属性都是存储在堆空间中的,两个对象分别存在不同空间,互不干扰。
内存图解析:
把age属性用static修饰之后
就会发现输出结果就是
结果发生了改变,先对p1赋值,之后p2赋值会干扰p1的age属性,可以说明两个对象共用一个属性。
内存解析:
总结:
1.在age属性被static修饰之后,就不属于person对象了,而是从属于类的。类成员属性随着类的加载而加载。
2.静态变量所有对象共享,在内存中之后一个数据,在类初始化就初始化
3.非静态变量属于对象,在对象创建时被初始化,各各对象的属性互不干扰。
2.用于方法,帮助我们更好的封装
static修饰的方法,在数据方面没有太大的变化,最主要的被static修饰的方法可以直接通过------类名.方法名调用-----也就不需要new一个新的对象去调用方法,这样大大减少了因创建对象引起的内存浪费,并且可以帮助我们更好的封装,把构造方法用private修饰之后,就不能通过new关键字创建对象,是能使用被static修饰的静态方法,通过----类名.方法名----调用。
隐藏了代码细节,对外只暴露出,被static修饰的方法,通过类名调用方法。提升了安全性。
代码:
public class Test4 {
public static void main(String[] args) {
Person.eat();
}
}
class Person{
String name;
static int age;
//私有化构造方法
private Person{
}
public static void eat(){
System.out.println("吃饭");
}
}
注意: static方法从属于类,是没有对象的,不依赖于任何对像,而我们的非静态变量和非静态方法都是需要具体的对象去调用的。所以静态方法不可以调用非静态方法和非静态成员,但非静态方法可以调用静态变量和静态方法的。
代码举例:
这段代码中有几处报错:
1.静态方法eat()中使用非静态变量id和name,编译的时候,类加载之后,对象还未创建,name和id还不存在。
2.静态方法中调用非静态方法,编译时,不知道非静态方法有没有使用非静态变量
静态代码块:这是为什么我们把程序入口main方法设置为static,在类加载时就创建,并且不需要对象去调用main方法,只需要类名就可以了
构造方法是对象的初始化,静态代码块是类的初始化。
语法:
static{
}
之前我们学习继承时,子类调用父类的成员方法,会先加载父类的构造方法-------》子类的构造方法-----》父类的成员方法。
现在我们加入静态代码块,这个时候先加载静态代码块,因为必须是先加载类之后再创建对象。
public class Test4 extends Person {
static{
System.out.println("我是静态代码块");
}
public static void main(String[] args) {
Test4 test4 = new Test4();//先加载父类,之后加载自己的,会有两个输出
Person person = new Person();
}
public Test4(){
System.out.println("我是子类的构造方法");
}
}
class Person{
String name;
int age;
//私有化构造方法
public Person(){
System.out.println("我是父类的构造方法");
}
public static void eat(){
System.out.println("吃饭");
}
}
结果:



