Java基础—static关键字(包括static内存原理,完整详解,附有代码+案例)

十一.static

11.1static静态变量

1.static 表示静态,是Java中的一个修饰符,可以修饰成员方法,成员变量;

2.被static修饰的成员变量叫做静态变量;被static修饰的成员方法叫静态方法。

3.静态变量在堆中的静态区

4.静态变量的特点:

  • 被该类所有的对象共享

  • 不属于对象,属于类

  • 随着类的加载而加载,优先于对象存在(加载).

  • (类内部,可在任何方法内直接访问静态变量)

    (其他类中,可以直接通过类名访问)

  • 在内存中只有一个拷贝

5.实例变量

没有被static修饰的变量每创建一个实例,就会为实例变量分配一次内存,实例变量可以在内存中有多个拷贝,互不影响

6.静态变量调用方式:

  • 类名调用

  • 对象名调用

public class Student {
    //属性:姓名 年龄 性别
    //新增:老师的姓名
    private String name;
    private int age;
    private String gender;
    public static String teacherName;//定义为静态变量
  
  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;}

//行为
public void study() {
    System.out.println(name + "正在学习");
}
public void show() {
    System.out.println(name + ", " + age + ", " + gender + ", " + teacherName);
}
}
public class StudentTest {
    public static void main(String[] args) {
       //类名调用静态变量,类中所有对象共享
        Student.teacherName = "小孔老师";
        //1.创建第一个学生对象
        Student s1 = new Student();
        s1.setName("张三");
        s1.setAge(23);
        s1.setGender("男");
        //s1.teacherName = "大孔老师";//对象调用静态变量
      
      s1.study();//张三正在学习
      s1.show();// 张三,23 ,男,小孔老师

    //2.创建第二个学生对象
    Student s2 = new Student();
    s2.setName("李四");
    s2.setAge(24);
    s2.setGender("女");
    //s2.teacherName = "大孔老师";//对象调用静态变量

    s2.study();// 李四正在学习
    s2.show();// 李四,24 ,女,小孔老师
}

11.2 static 内存图

静态变量在堆中的静态区
(图片来自B站)
在这里插入图片描述

当对象s2的name 、age 没有赋值时,输出的是默认值。

每new一次会在堆中开辟一小块空间。
(图片来自B站Java视频)
在这里插入图片描述

11.3 static-静态方法

被static 修饰的成员方法,叫静态方法。

特点:

  • 多用在测试类中和工具类中

  • JavaBean类中很少会用

调用方式:

  • 类名调用

  • 对象名调用

11.3.1工具类

帮助我们做一些事情的,但是不描述任何事物的类。

工具类不需要创建对象。

工具类注意事项:

  • 类名要见名知意
  • 私有化构造方法:不让外界创建它的对象
  • 方法定义为静态
11.3.1.1案列1

定义工具类方法:
1.用户返回整数数组的内容,返回的字符串格式如[1,2,3],只考虑一维数组
2.提供一个工具方法getAverage用户返回平均值,只考虑浮点型,一维数组

定义测试类,调用工具类里的工具方法,并返回结果

public class ArrayUtil {
    // 私有化构造方法
    // 目的:为了不让外界创捷它的对象
    private ArrayUtil (){}

    // 其他方法定义为静态
    // 目的:方便外界调用
    // 定义工具类方法:
    // 1.用户返回整数数组的内容,返回的字符串格式如[1,2,3],只考虑一维数组
    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]);
            }else {
                sb.append(arr[i] + ",");
            }
        }
        sb.append("]");
        return sb.toString();
    }
    // 2.提供一个工具方法getAverage用户返回平均值,只考虑浮点型,一维数组
    public static double getAverage(double[] arr){
        double sum = 0;
        for (int i = 0; i < arr.length; i++) {
            sum = sum +arr[i];
        }
        return sum/arr.length;
    }

public class ArrayUtilTest {
    public static void main(String[] args) {
        // 定义测试类,调用工具类里的工具方法,并返回结果
        int[] arr1 = {1,2,3};
        // 用 类名调用
        String s = ArrayUtil.printArr(arr1);
        System.out.println(s);

        double[] arr2 = {5,5,5,5};
        double average = ArrayUtil.getAverage(arr2);
        System.out.println("平均分:"+average);

    }
}
11.3.1.2 案例2

定义学生工具类

  • 需求:定义一个集合,用于存储3个学生对象

  • 学生类的属性为:name /age/gender

  • 定义一个工具类,用于获取集合中最大学生的年龄

// 标准学生JavaBean类
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;
    }
}
// 工具类 求最大年龄
import java.util.ArrayList;
public class StudentUtil {
    // 私有化构造方法
    private StudentUtil(){}
    // 定义一个求最大年龄的方法
    public static int getAge(ArrayList<Student> list){
        // 初始默认集合中的第一个元素对象的年龄最大
        int ageMax = list.get(0).getAge();
        for (int i = 0; i < list.size(); i++) {
            //i 索引  list.get(i)元素/学生对象  还需要getAge获取到年龄之后再进行比较
            int tempAge = list.get(i).getAge();
            if (tempAge>ageMax){
              ageMax = tempAge;
            }
        }
        return ageMax;
    }
}

//测试类
import java.util.ArrayList;
public class StudentTest {
    public static void main(String[] args) {
        // 创建集合
        ArrayList<Student> list = new ArrayList<>();
        // 创建对象并赋值
        Student s1 = new Student("小孔",18,"男");
        Student s2 = new Student("大聪明",19,"女");
        Student s3 = new Student("小聪明",120,"女");
        // 将学生对象添加到集合中
        list.add(s1);
        list.add(s2);
        list.add(s3);
				//调用工具类中的方法
        int ageMaxEnd = StudentUtil.getAge(list);
        System.out.print("最大年龄为:"+ageMaxEnd);

    }
}

11.4静态代码块

静态代码块:

格式:static{ }

特点:需要通过static关键字修饰,随着类的加载而加载,并且自动触发,只执行一次

使用场景:在类加载时,做一些数据初始化的时候使用。

11.5 static 注意事项

  • 静态方法只能访问静态变量和静态方法

    (即 静态方法不能直接访问所属类的实例变量和实例方法)

  • 非静态方法可以访问静态变量或静态方法,也可以访问非静态的成员变量和非静态的成员方法。(即 非静态方法可以访问所有)

  • 静态方法中没有this关键字

  • 在实例方法里不可以定义static变量,但是可以访问静态变量

总结:

  • 静态方法中没有this关键字

    静态是所有对象共享的,所以在使用时跟具体某个对象的调用无关,所以没有this。

  • 静态方法中,只能访问静态

    如果在静态方法中,访问非静态成员变量,就会出现不知道访问该变量是哪个对象的成员变量;如果要访问指定对象的变量,需要加上this关键字,但在静态方法中没有this关键字。因此不能访问非静态成员变量。

  • 非静态方法中可以访问所有

    非静态的东西跟对象有关,静态变量和静态方法的调用都可以用对象名调用,所以用对象名方式的调用可以访问静态和非静态。

**在非静态成员方法的形参当中有个隐藏的 this.**如下代码所示:

在这里插入图片描述

//上述输出结果为:
stringstaticdemo.demo3.Student@1540e19d
this:stringstaticdemo.demo3.Student@1540e19d
大聪明.18.小孔
这是show2
========
stringstaticdemo.demo3.Student@677327b6
this:stringstaticdemo.demo3.Student@677327b6
小聪明.19.小孔
这是show2

11.6重识main

  • public:被jvm调用,访问权限足够大

  • static:被jvm调用,不能创建对象,直接类名访问。

    因为main 方法是静态,所以测试类中其他方法也需要是静态的

  • void:被jvm调用,不需要给jvm返回值

  • main:一个通用的名称,虽不是关键字,但可以被jvm识别

  • 8
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蔚一

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值