【java】static 关键字
static 修饰符可以修饰:变量、方法和代码块 。
➢用 static 修饰的变量和方法,可以采用类名直接访问
➢用 static 声明的代码块为静态代码块,JVM 加载类的时候,会执行静态代码块中的内容
1、采用静态变量实现累加器
public class StaticTest01 {
public static void main(String[] args) {
Student student1 = new Student(1001, "张三", true, "北京", 20);
Student student2 = new Student(1002, "李四", true, "上海", 30);
System.out.println(student1.getCount());
System.out.println(student2.getCount());
}
}
class Student {
//学号
private int id;
//姓名
private String name;
//性别
private boolean sex;
//地址
private String address;
//年龄
private int age;
//计数器,计算 student 的创建个数
private int count;
public Student(int id, String name, boolean sex, String address, int age) {
count++;
this.id = id;
this.name = name;
this.sex = sex;
this.address = address;
this.age = age;
}
//返回计数器
public int getCount() {
return count;
}
}
以上输出不正确,因为采用的是成员变量作为累加器,成员变量只属于某一个对象,如果多 个对象那么成员变量会有多个拷贝,对象中的成员变量都是私有的,某一个对象中的成员变 量的改变不会影响到另一个对象中的成员变量的改变 。
public class StaticTest01 {
public static void main(String[] args) {
Student student1 = new Student(1001, "张三", true, "北京", 20);
Student student2 = new Student(1002, "李四", true, "上海", 30);
System.out.println(student1.getCount());
System.out.println(student2.getCount());
}
}
class Student {
//学号
private int id;
//姓名
private String name;
//性别
private boolean sex;
//地址
private String address;
//年龄
private int age;
//计数器,计算 student 的创建个数
private static int count;
public Student(int id, String name, boolean sex, String address, int age) {
count++;
this.id = id;
this.name = name;
this.sex = sex;
this.address = address;
this.age = age;
}
//返回计数器
public int getCount() {
return count;
}
}
static 声明的变量,所有通过该类 new 出的对象,都可以共享,通过该对象都可以直接访问 static 声明的变量,也可以采用类直接访问,所以我们也称其为类变量
static 声明的变量会放到方法区中,static 声明的变量只初始化一次,加在类的时候初始化,如果多个静态变量,会按照静态变量在类中的顺序进行初始化。
2、静态方法中访问实例变量、实例方法或 this 关键字
2.1 静态方法中是不能直接调用实例变量、实例方法和使用 this 的
也就是说和实例相关的他都不能直接调用。
public class StaticTest04 {
public static void main(String[] args) {
//在静态区域中不能直接调用成员方法
//因为静态方法的执行不需要 new 对象
//而成员方法必须 new 对象后才可以执行
//所以执行静态方法的时候,对象还没有创建
//所以无法执行成员方法
method1();
}
public void method1() {
System.out.println("method1");
}
}
静态区域中不能直接调用成员方法,因为静态方法的执行不需要 new 对象,而成员方法必须 new 对象后才能执行,所以执行静态方法的时候,对象还没有创建,故无法执行成员方法 。
2.2 在静态区域中成功调用实例方法
public class StaticTest05 {
public static void main(String[] args) {
StaticTest05 staticTest05 = new StaticTest05();
//在静态区域中如果访问成员方法必须具有
//该成员方法对应的对象引用
staticTest05.method1();
}
public void method1() {
System.out.println("method1");
}
}
在静态区域中成功调用实例方法 :在静态区域中如果访问成员方法必须具有该成员方法对应的对象引用。
2.3 在静态区域中可以直接调用静态方法
public class StaticTest06 {
public static void main(String[] args) {
//可以直接调用
//method1();
//可以采用类名+方法调用
StaticTest06.method1();
}
public static void method1() {
System.out.println("method1");
}
}
静态区域中可以直接调用静态方法 :可以直接调用,可以采用类名+方法调用。
2.4 在静态区域中调用成员(实例)变量
public class StaticTest07 {
//private int age = 100;
private static int age = 100;
public static void main(String[] args) {
//在静态区域中无法直接访问成员变量
//System.out.println(age);
//可以采用对象的引用调用
//StaticTest07 staticTest07 = new StaticTest07();
//System.out.println(staticTest07.age);
//直接取得静态变量的值
//System.out.println(age);
//可以采用类名+属性名 访问
System.out.println(StaticTest07.age);
}
}
在静态区域中无法直接访问成员变量,可以采用对象的引用调用;直接取得静态变量的值可以采用类名+属性名访问。
2.5 在静态区域中使用 this
public class StaticTest08 {
private int age = 100;
public static void main(String[] args) {
//因为执行 main 方法的时候,还没有该对象
//所以 this 也就不存在,无法使用
System.out.println(this.age);
}
}
因为执行main方法的时候,还没有该对象,所以this也就不存在,无法使用。
3、静态方法的初始化顺序
上面已经说到,静态变量在类加载时就会初始化,也就是将类的字节码读取到方法区时就会初始化
public class StaticTest09 {
private static int age = 100;
static {
System.out.println("---------静态语句块 1---------");
}
static {
System.out.println("---------静态语句块 2---------");
}
static {
System.out.println("---------静态语句块 3---------");
}
static {
System.out.println("---------静态语句块 4---------");
System.out.println("age=" + age);
}
public static void main(String[] args) {
System.out.println("-------------main----------------");
}
}
Static 声明的变量或 static 语句块在类加载时就会初始化(不是完全正确),而且只初始化一次 。
4、解释 main 方法
解释 main 方法:
(1)public:表示全局所有,其实就是封装性
(2)static:静态的,也就是说它描述的方法只能通过类调用
(3)main:系统规定的
(4)String[] args 参数类型也是系统规定的
以上为什么是静态方法,应该很显然,这样 java 虚拟机调用起来会更方便,直接拿到类就可以调用 main 方法了,而静态的东西都在方法区中,那么你在静态方法里调用成员属性,它在方法区中无法找到,就算到堆区中查找,可能此成员属性的对象也没有创建,所以静态方法中是不能直接访问成员属性和成员方法的。
本文地址:https://blog.csdn.net/Zhouzi_heng/article/details/110160169