学习Java36天

Java 中的 static 关键字

static 是 Java 的一个修饰符,用于修饰类的成员 (变量和方法)。它的核心思想是与类相关联,而不是与类的任何一个特定对象(实例)相关联

一、静态变量(类变量)
  • 定义 :被 static 修饰的成员变量。

  • 特点

    1. 共享性 :被该类创建的所有对象所共享。在内存中只有一个副本。

    2. 类属性 :它不属于任何一个对象,而是属于定义它的类本身

    3. 生命周期 :随着类的加载而加载到内存中的"静态区",优先于对象的创建而存在。直到程序结束才会被销毁。

  • 调用方式

    • 类名.变量名 (推荐,明确其静态属性)

    • 对象名.变量名 (不推荐,容易混淆)

示例

java

复制代码
class Student {
    String name;
    // 静态变量:所有学生共享的学校名称
    static String school = "第一中学";

    public Student(String name) {
        this.name = name;
    }
}

public class Main {
    public static void main(String[] args) {
        Student s1 = new Student("小明");
        Student s2 = new Student("小红");

        System.out.println(s1.name + " 的学校是:" + Student.school); // 小明 的学校是:第一中学
        System.out.println(s2.name + " 的学校是:" + Student.school); // 小红 的学校是:第一中学

        // 通过类名修改静态变量,所有对象看到的都变了
        Student.school = "实验中学";
        System.out.println(s1.name + " 的学校现在是:" + Student.school); // 小明 的学校现在是:实验中学
    }
}

二、静态方法(类方法)
  • 定义 :被 static 修饰的成员方法。

  • 特点

    1. 常用于工具类测试类

    2. 在标准的 JavaBean 类(主要用于描述事物的类,如 Student, User)中较少使用。

  • 调用方式

    • 类名.方法名() (推荐)

    • 对象名.方法名() (不推荐)

示例

java

复制代码
// 工具类示例:数学工具
class MathUtils {
    // 私有构造方法,防止别人创建对象
    private MathUtils() {}

    // 静态方法,方便直接通过类名调用
    public static int add(int a, int b) {
        return a + b;
    }
    public static double circleArea(double radius) {
        return Math.PI * radius * radius;
    }
}

public class Main {
    public static void main(String[] args) {
        // 无需创建 MathUtils 对象,直接使用
        int sum = MathUtils.add(5, 3);
        double area = MathUtils.circleArea(2.5);
        System.out.println("和: " + sum); // 和: 8
        System.out.println("面积: " + area); // 面积: 19.634954...
    }
}

三、工具类设计模式

这是静态方法的典型应用场景。

  • 定义:一个只包含静态方法和静态变量的类,用于提供通用功能,而不描述任何具体事物。

  • 设计规范

    1. 类名见名知意 (如 Arrays, Collections, MathUtils, StringUtils)。

    2. 提供私有构造方法private 修饰构造器),防止外界通过 new 创建实例,强调其"工具"属性。

    3. 方法定义为静态的,方便通过类名直接调用。


四、static 的注意事项(重点)

这是理解 static 的关键,涉及访问权限this 关键字

方法类型 可以访问 不可以直接访问 原因解释
静态方法 静态成员(变量/方法) 非静态成员(实例变量/方法) 静态方法在类加载时就存在,此时可能还没有任何对象被创建。非静态成员属于对象,没有对象就无法访问。
非静态方法 所有成员(静态 + 非静态) (无) 非静态方法必须通过对象调用。当对象存在时,静态成员(属于类)和非静态成员(属于该对象)都已确定存在。
  • this 关键字

    • this 代表当前对象的引用

    • 因为静态方法可以通过 类名.方法名() 调用,此时没有"当前对象"的概念,所以静态方法中不能使用 this 关键字

    • 非静态方法必须由对象调用,所以内部可以使用 this

示例

java

复制代码
class Example {
    int instanceVar = 10; // 实例变量(非静态)
    static int staticVar = 20; // 静态变量

    // 非静态方法
    public void nonStaticMethod() {
        System.out.println(instanceVar); // OK,访问自己的
        System.out.println(staticVar);   // OK,访问静态的
        this.instanceVar = 30; // OK,this 存在
        staticMethod(); // OK,调用静态的
    }

    // 静态方法
    public static void staticMethod() {
        // System.out.println(instanceVar); // 编译错误!不能访问非静态变量
        System.out.println(staticVar);   // OK,访问静态的
        // this.staticVar = 40; // 编译错误!不能使用 this
        // nonStaticMethod();   // 编译错误!不能调用非静态方法
    }
}

总结

  • 核心区分静态属于类,非静态属于对象

  • 访问规则静态方法只能访问静态成员。非静态方法可以访问所有。

  • this :静态方法中没有 this

  • 设计思想:将与对象状态无关的、通用的功能设计为静态方法和工具类,提高代码的复用性和组织性。将与对象状态相关的行为设计为非静态方法。

java 复制代码
package a01staticdemo1;

public class StudentText {
    public static void main(String[] args) {
        Student.teacherName = "YUQI";
        //1.创建第一个学生对象
        Student s1 = new Student();
        s1.setName("张三");
        s1.setAge(18);
        s1.setGender('男');
        //s1.teacherName = "yuqi";

        s1.study();
        s1.show();

        //1.创建第二个学生对象
        Student s2 = new Student();
        s2.setName("李四");
        s2.setAge(20);
        s2.setGender('男');

        s2.study();
        s2.show();
    }
}


package a01staticdemo1;

public class Student {
    //属性:姓名 年龄 性别
    private String name;
    private int age;
    private char gender;
    //新增:老师的姓名
    public static  String teacherName;

    public Student(String name, int age, char gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    public Student() {

    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public char getGender() {
        return gender;
    }

    public void setGender(char gender) {
        this.gender = gender;
    }

    public void study(){
        System.out.println(name+"正在学习");
    }
    public void show(){
        System.out.println(name+", "+age+", "+gender+", "+teacherName);
    }
}
java 复制代码
package a02staticdemo2;

public class TextDemo {
    public static void main(String[] args) {
        int[] arr1 = {1,2,3,4,5,6};
        String str = ArrayUtil.printArr(arr1);
        System.out.println(str);
        double[] arr2 = {4.5,3.5,9.6,7.2};
        double avg = ArrayUtil.getAverage(arr2);
        System.out.println(avg);
    }
}


package a02staticdemo2;

public class ArrayUtil {

    //私有化构造方法
    //目的:为了不让外界创建他的对象
    private ArrayUtil(){
    }
    //需要定义为静态方便调用
    public static String printArr(int[] arr){
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for (int i = 0; i < arr.length; i++) {
            if (i == arr.length-1){
                sb.append(arr[i]).append("] ");
            }else {
                sb.append(arr[i]).append(", ");
            }
        }
        return sb.toString();
    }
    public static double getAverage(double[] arr){
        double sum = 0;
        for (int i = 0; i < arr.length; i++) {
            sum += arr[i];
        }
        return sum/ arr.length;
    }
}
java 复制代码
package a03staticdemo3;


import java.util.ArrayList;

public class TextDemo {
    public static void main(String[] args) {
        ArrayList<Student> list = new ArrayList<>();

        Student s1 = new Student("zhangsan",23,"nan");
        Student s2 = new Student("lisi",24,"nv");
        Student s3 = new Student("wangwu",25,"nan");

        list.add(s1);
        list.add(s2);
        list.add(s3);

        int max = StudentUtil.getMaxAgeStudent(list);

        System.out.println(max);
    }
}


package a03staticdemo3;

import java.util.ArrayList;

public class StudentUtil {

    private StudentUtil(){}

    public static int getMaxAgeStudent(ArrayList<Student> list){
        int max = list.get(0).getAge();
        for (int i = 1; i < list.size(); i++) {
            int tempAge = list.get(i).getAge();
            if ((tempAge > max)){
                max = list.get(i).getAge();
            }
        }
        return max;
    }
}


package a03staticdemo3;

public class Student {
    private String name;
    private int age;
    private String gender;

    public Student() {
    }

    public Student(String name, int age, String gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }
}
相关推荐
夕除17 小时前
js--6
java·开发语言
ytttr87317 小时前
C#实现海康威视智能车牌识别
开发语言·c#
梵刹古音17 小时前
【C语言】 关键字与用户标识符
c语言·开发语言
悟能不能悟17 小时前
grpc协议
开发语言
知识分享小能手17 小时前
Oracle 19c入门学习教程,从入门到精通,Oracle优化SQL语句 — 语法知识点与使用方法详解(16)
sql·学习·oracle
calvinpaean17 小时前
Metric3D Towards Zero-shot Metric 3D Prediction from A Single Image 论文学习
学习·3d
四维碎片17 小时前
【Qt】代理(Delegate)的使用
开发语言·qt
手握风云-17 小时前
JavaEE 进阶第十三期:Spring Ioc & DI,从会用容器到成为容器(下)
java·spring·java-ee
组合缺一17 小时前
论 AI Skills 分布式发展的必然性:从单体智能到“云端大脑”的跃迁
java·人工智能·分布式·llm·mcp·skills
砚边数影17 小时前
决策树原理(一):信息增益与特征选择 —— Java 实现 ID3 算法
java·数据库·决策树·机器学习·kingbase·数据库平替用金仓·金仓数据库