static关键字
static关键字概念
static关键字是静态的意思,可以修饰【成员变量】,【成员方法】,【代码块】
static关键字特点
- 被类的所有对象共享,这也是我们判断是否使用静态关键字的条件
- 可以通过类名调用当然,也可以通过对象名调用【推荐使用类名调用】
- static修饰的东西和对象无关
static关键字修饰成员变量
- 语法格式:static 变量类型 变量名;
- 加载时间:代码中没有创建任何类对象的时候,static修饰的成员变量已经加载。
- 分析内存:只要是static修饰的成员变量,都是在.class【字节码文件】文件,编译阶段,就直接加载到了内存的数据区。该过程是早于对象的创建的,整个数据区静态的成员属性是伴随着整个程序的结束而结束。
- 保存区域:类对象 堆区。静态的成员属性保存在数据区
代码示例如下:
package com.wzl.cpp;
public class Person01 {
// 非静态成员变量
String name;
int age;
// 静态成员变量
static String name1;
static int age1;
}
//static关键字
public class test01 {
public static void main(String[] args) {
// 静态成员变量可以通过类名直接调用,不需要通过对象调用,并且在没有创建对象时就可以调用静态代码块
Person01.name1="蜜雪冰城";
Person01.age1=20;
System.out.println(Person01.name1);
System.out.println(Person01.age1);
// 通过创建对象调用非静态成员变量
Person01 person01 = new Person01();
person01.name="星巴克";
person01.age=30;
System.out.println(person01.name);
System.out.println(person01.age);
// 通过对象也可以调用静态成员变量,和使用类名调用的静态成员变量是一个变量,在上面赋值过后可以直接打印
// 也就是说在一个类当中的同一个名字的静态成员变量只有一个,不管用类名还是任意一个该类创建的对象都是这一个
// 但是不推荐使用对向调用静态成员变量
System.out.println(person01.name1);
System.out.println(person01.age1);
}
}
运行结果如下:
static关键字修饰成员方法
- 语法格式:public static void 方法名(){}
- 加载时间:代码中没有创建任何类对象的时候,static修饰的成员方法已经加载。
- 内存分析:静态的成员方法随着.class文件的加载而加载。会被加载到方法区。这个时候方法的创建要早于对象的创建。
- 注意:.静态的成员方法中能不能使用非静态的成员属性和非静态的成员方法,因为静态方法是在.class文件1加载时就加载到方法区的,这时非静态的成员变量还未加载到内存当中,不能使用
- 静态的方法不能被重写,静态方法默认带有final关键字,不能被重写
- 静态方法中可以的创建的对象
代码示例如下:
public class Person02 {
public static void eat(){
System.out.println("我这是静态的成员方法。");
}
public void eat2(){
System.out.println("我这不是静态的成员方法。");
}
}
public class test02 {
public static void main(String[] args) {
// 使用static修饰的成员方法叫静态成员方法,静态成员方法可以通过类名直接调用
// 在不创建对象时就可以通过类名直接调用
Person02.eat();
// 通过创建对象调用非静态成员方法
Person02 person02 = new Person02();
person02.eat2();
// 通过对象也可以调用静态成员方法,但是不推荐使用对向调用静态成员变量
person02.eat();
}
}
运行结果如下
static关键字修饰的代码块
语法格式:static{代码块}
java当中用{}括起来的代码块一共有四种
- 普通代码块
类中方法的方法体 - 构造代码块
构造块会在创建对象时被调用,每次创建时都会被调用,优先于类构造函数执行。 - 静态代码块
用static{}包裹起来的代码片段,只会执行一次。静态代码块优先于构造块执行。 - 同步代码块
使用synchronized(){}包裹起来的代码块,在多线程环境下,对共享数据的读写操作是需要互斥进行的,否则会导致数据的不一致性。同步代码块需要写在方法中。
静态代码块和构造代码块的相同点和不同点
- 相同点
都是JVM加载类后且在构造函数执行之前执行,在类中可定义多个,一般在代码块中对一些static变量进行赋值。 - 不同点
静态代码块在非静态代码块之前执行。静态代码块只在第一次new时执行一次,之后不在执行。而非静态代码块每new一次就执行一次。
构造代码块示例如下:
public class Person04 {
{
System.out.println("我是构造代码块。");
}
public Person04() {
System.out.println("我是构造方法");
}
}
public class test04 {
public static void main(String[] args) {
new Person04();
new Person04();
new Person04();
}
}
运行结果如下:
注意:
- 构造代码块:直接在类中定义且没有加static关键字的代码块称为{}构造代码块。构造代码块在创建对象时被调用,每次创建对象都会被调用,并且构造代码块的执行次序优先于类构造函数。如果存在多个构造代码块,执行顺序由他们在代码中出现的次序决定,先出现先执行。
静态代码块示例如下:
public class Person03 {
public Person03() {
System.out.println("我是构造方法");
}
static {
System.out.println("我是静态代码块。我的优先级比构造方法要高");
}
}
public class test03 {
public static void main(String[] args) {
Person03 person03 = new Person03();
}
}
运行结果如下
注意:
- 静态代码块是在java中使用static关键字声明的代码块。静态块用于初始化类,为类的属性初始化。每个静态代码块只会执行一次。由于JVM在加载类时会执行静态代码块,所以静态代码块先于主方法执行。如果类中包含多个静态代码块,那么将按照"先定义的代码先执行,后定义的代码后执行"。
- 静态代码块不能存在于任何方法体内。
- 静态代码块不能直接访问实例变量和实例方法,需要通过类的实例对象来访问。
总结
以上内容就是有关java当中static关键字的相关内容,希望对大家有所帮助。如有不足,感谢指出。