从零学Java - 面向对象 Static

发布时间:2024年01月05日

面向对象 Static

1.什么是静态?

概念: 共享的, 共有的;

基本用法:

  • 静态(static)可以修饰属性,称为静态属性(类属性)。
  • 静态(static)可以修饰方法,称为静态方法(类方法)。

特点

  • 静态成员是类所有对象共享的成员,在全类中只有一份,不因创建多个对象而产生多份。
  • 静态成员访问不必创建对象,可直接通过类名访问。

使用场景:

  • 一般工具类中属性和方法都是静态的。比如:Arrays、Math
  • 如果这个属性或方法只需要一份,使用静态修饰。比如:main方法

2.Static的作用

2.1 属性

2.1.1 实例属性

实例属性是每个对象各自持有的独立空间(多份),对象单方面修改,不会影响其他对象。

eg:

public class Test {
    public static void main(String[] args) {

        Student stu_1 = new Student();
        stu_1.name = "小明";

        Student stu_2 = new Student();
        stu_2.name = "小红";
    }
}

public class Student {
    String name;
}
2.1.2 静态属性

静态属性是整个类共同持有的共享空间(一份),任何对象修改,都会影响其他对象。

eg:

public class Test {
    public static void main(String[] args) {
        System.out.println("使用类名访问静态属性");
        Student.count = 2000;
        System.out.println("学生数量为:"+Student.count);
    }
}

public class Student {
    static int count;
}

eg:

练习:统计一个类的对象被创建过多少次?
//Student
public class Student {
    String name;
    int age;
    String gender;
    double score;

    //默认为0, 创建对象的次数
    public static int count;

    public Student() {
        Student.count++;
    }

    public Student(String name, int age, String gender, double score) {
        Student.count++;
        this.name = name;
        this.age = age;
        this.gender = gender;
        this.score = score;
    }
}
//Test
public class Test {
    public static void main(String[] args) {

        Student stu_1 = new Student();

        stu_1.name = "小明";
        stu_1.age = 18;
        stu_1.gender = "男";
        stu_1.score = 100;

        Student stu_2 = new Student();

        stu_2.name = "小红";
        stu_2.age = 18;
        stu_2.gender = "女";
        stu_2.score = 100;

        Student stu_3 = new Student("小绿", 20, "男", 98);

        System.out.println("使用类名访问静态属性");
        System.out.println("学生数量为:"+Student.count);
    }
}

2.2 方法

2.2.1 静态方法

被 static 修饰的方法, 称为静态方法;

public class Student {
    //默认为0, 创建对象的次数
    public static int count;
    
    public static void calcCount() {
    	System.out.println("开始统计...");
    	Student.count = 2000;
    	System.out.println("统计结束...");
        //可在本类中,通过“静态方法名”访问
        method();  // Student.method();
	}
    
    public static void method() {
        // 方法体
    }
}

public class Test {
     public static void main(String[] args) {
         System.out.println("使用类名访问静态方法");
         //可在其他类中,通过“类名.静态方法名”访问
		Student.calcCount();
		System.out.println("学生数量为:"+Student.count);
     }
}
  • 可在本类中, 通过 “静态方法名” 访问;
  • 可在其他类中, 通过 “类名.静态方法名” 访问;

特点:

  • 静态方法允许直接访问静态属性和静态方法。
  • 静态方法不能直接访问实例属性和实例方法,需要创建对象访问。
  • 非静态方法中可以直接访问静态属性和静态方法。
  • 静态方法中不允许使用this或是super关键字。
  • 静态方法可以被继承,可以重载,不能被重写(重写只存在于实例方法之间)。

2.3 代码块

2.3.1 局部代码块

局部代码块:定义在方法内部的代码块。

eg:

public class TestBlock {
    public static void main(String[] args) {
        int num1 = 100;
        {
            int num2 = 200;
            System.out.println(num1);
            System.out.println(num2);
        }
    }
}

作用: 会缩小变量的使用范围,提前释放局部变量,节省内存。

2.3.2 动态代码块

动态代码块:定义在方法外,类内部的代码块。

执行时机:创建对象时,触发动态代码块的执行。作用:可为实例属性初始化。

代码编译后会将动态代码块中的内容添加到每个构造方法的首行;

eg:

//Student
public class Student {
    String name;

    public Student() {
        //System.out.println("动态代码块执行了");
    }
    
    public Student(String name) {
        //System.out.println("动态代码块执行了");
        this.name = name;
    }
    
    //动态代码块
    {
        System.out.println("动态代码块执行了");
    }
}
2.3.3 静态代码块

静态代码块:使用static修饰的动态代码块。

执行时机类加载时,触发静态代码块的执行(仅一次)。

作用:可为静态属性初始化。

eg:

//Student
public class Student {
    String name;

    public Student() {
    }
    
    public Student(String name) {
        this.name = name;
    }
    
    //静态代码块
    static {
        System.out.println("静态代码块执行了");
    }
}

2.4 静态导入

eg:

package StageOne.day12.demo04;
import static java.lang.System.out;
/**
 * @author 胡昊龙
 * @version 1.0
 * @description: TODO
 * @date 2024/1/4 16:33
 */
public class TestImportStatic {
    public static void main(String[] args) {
        out.println("静态导入");
    }
}

3.类加载

3.1 什么是类加载?

JVM首次使用某个类时,需通过CLASSPATH查找该类的.class文件。
将.class文件中对类的描述信息加载到内存中,进行保存。如:包名、类名、父类、属性、方法、构造方法…

3.2 触发类加载的5种情况

  • 创建对象。

    Student s=new Student();
    
  • 创建子类对象。

    class CollegeStudent extends Student {...}
    
    CollegeStudent stu = new CollegeStudent();
    
  • 访问静态属性。

    static int count; //静态属性
    
    System.out.println(Student.count);
    
  • 调用静态方法。

    public static void method() {...} // 静态方法
    
    Student.method();
    
  • 主动加载:Class.forName(“全限定名”);//后面讲

3.3 类加载过程的5个阶段

类加载的五个阶段:

  • 加载—>链接 (验证—>准备—>解析)—>初始—>使用—>卸载

准备:为类的静态属性分配空间,并赋值默认值(静态常量除外)

初始化:从上到下执行静态变量赋值,静态代码块

4.面试题

eg:

阅读下方代码, 请说明运行结果和具体的执行过程
public class TestStatic {
    public static void main(String[] args) {
        Demo.show();
    }
}
class Demo {
    static {
        Demo.count1++;
        Demo.count2++;
    }
    private static Demo demo = new Demo();
    public static int count1;
    public static int count2=0;
    
    public Demo() {
        Demo.count1++;
        Demo.count2++;
    }
    
    public static void show() {
        System.out.println("count1:"+count1);
        System.out.println("count2:"+count2);
    }
}

res:

count1:2
count2:0
文章来源:https://blog.csdn.net/weixin_50858647/article/details/135392541
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。