Java|面向对象(下)-- static 关键字

一. static 关键字介绍

Java 中的 static 关键字主要用于内存管理。我们可以应用 Java static 关键字在变量、方法、代码块和内部类中。static 关键字属于类,而不是类的实例。
静态(static)修饰如下:

  • 变量:称为类变量、静态变量
  • 方法:称为类方法、静态方法
  • 代码块:称为静态代码块
  • 嵌套类:称为静态内部类

二. static 关键字的使用

2.1 静态变量

类的成员变量可以分为以下两种:

  1. 静态变量(或称为类变量),指被 static 修饰的成员变量。
  2. 实例变量,指没有被 static 修饰的成员变量。

静态变量与实例变量的区别如下:
1)静态变量

  • 运行时,Java 虚拟机只为静态变量分配一次内存,加载类过程中完成静态变量的内存分配。存在方法区的静态域中
  • 在类的内部,可以在任何方法内直接访问静态变量。
  • 在其他类中,可以通过类名访问该类中的静态变量。

2)实例变量

  • 每创建一个实例,Java 虚拟机就会为实例变量分配一次内存。
  • 在类的内部,可以在非静态方法中直接访问实例变量。
  • 在本类的静态方法或其他类中则需要通过类的实例对象进行访问。

静态变量在类中的作用如下:

  • 静态变量可以被类的所有实例共享,因此静态变量可以作为实例之间的共享数据,增加实例之间的交互性。
  • 如果类的所有实例都包含一个相同的常量属性,则可以把这个属性定义为静态常量类型,从而节省内存空间。例如,在类中定义一个静态常量 PI

调用关系:

类变量实例变量
yesno
对象yesyes
package com.base.learn;

public class StaticTest {
    public static void main(String[] args) {
        Chinese.nation = "中国";

        Chinese c1 = new Chinese();
        c1.name = "姚明";
        c1.age = 40;
        c1.nation = "CHN";

        Chinese c2 = new Chinese();
        c2.name = "马龙";
        c2.age = 40;
        c2.nation = "CHINA";

        System.out.println(Chinese.nation); // CHINA
    }
}

class Chinese {
    String name;
    int age;
    static String nation;
}

在这里插入图片描述

2.2 静态方法

与成员变量类似,成员方法也可以分为以下两种:

  1. 静态方法(或称为类方法),指被 static 修饰的成员方法。
  2. 实例方法,指没有被 static 修饰的成员方法。

静态方法与实例方法的区别:

  1. 静态方法,属于类,而不属于类的对象。
    1. 它通过类直接被调用,无需创建类的对象。
    2. 静态方法中,不能使用 this 关键字,也不能直接访问所属类的实例变量和实例方法。
    3. 静态方法中,可以直接访问所属类的静态变量和静态方法。
    4. 同 this 关键字,super 关键字也与类的实例相关,静态方法中不能使用 super 关键字。
  2. 实例方法,可直接访问所属类的静态变量、静态方法、实例变量和实例方法。

调用关系:

静态方法非静态方法
yesno
对象yesyes

注意:关于静态属性和静态方法的使用,要从声明周期的角度去理解(随着类的加载而加载)

静态方法与静态变量好处:

  1. 属于类级别,无需创建对象就即可直接使用,使用方便。
  2. 全局唯一,内存中唯一,静态变量可以唯一标识某些状态。
  3. 类加载时候初始化,常驻在内存,调用快捷方便。

静态方法与静态变量缺点:

  1. 静态方法不能调用非静态的方法和变量。
  2. 不能使用 this 和 super 关键字。

静态方法与静态变量适用场景:

  1. 静态方法,最适合工具类中方法的定义;比如文件操作,日期处理方法等。
  2. 静态方法,适合入口方法定义;比如单例模式,因从外部拿不到构造函数,所以定义一个静态的方法获取对象非常有必要。
  3. 静态变量适合全局变量的定义;举例:用一个布尔型静态成员变量做控制标志。

static 的应用举例

package com.base.learn;

public class CircleTest {
    public static void main(String[] args) {
        Circle c1 = new Circle();
        System.out.println("c1 的 ID:" + c1.getId());

        Circle c2 = new Circle();
        System.out.println("c2 的 ID:" + c2.getId());

        Circle c3 = new Circle(3.4);
        System.out.println("c3 的 ID:" + c3.getId());

        System.out.println("创建圆的个数:" + Circle.getTotal());

    }
}

class Circle {
    private double radius; // 半径
    private int id; // 编号,自动赋值
    private static int total; // 记录创建圆的个数
    private static int init = 1001;

    public Circle() {
        id = init++;
        total++;
    }

    public Circle(double radius) {
        this();
        this.radius = radius;
    }

    // 求圆的面积
    public double findArea() {
        return Math.PI * radius * radius;
    }

    public double getRadius() {
        return radius;
    }

    public void setRadius(double radius) {
        this.radius = radius;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public static int getTotal() {
        return total;
    }
}

static 练习题

package com.base.learn;

/**
 * 编写一个类实现银行账户的概念,包含的属性有“帐号”、“密码”、“存款余额”、
 * “利率”、“最小余额”,定义封装这些属性的方法。
 * 账号要自动生成。编写主类,使用银行账户类,输入、输出 3 个储户的上述信息。
 * 考虑:哪些属性可以设计成 static 属性。
 */
public class Account {
    private int id; // 账号
    private String pwd = "000000"; // 初始密码
    private double balance; // 存款余额

    private static double interestRate; // 利率
    private static double minMoney = 1.0; // 最小余额
    private static int init = 1001; // 用于自动生成 ID

    public Account() {
        this.id = init++;
    }

    public Account(String pwd, double balance) {
        this();
        this.pwd = pwd;
        this.balance = balance;
    }

    public String getPwd() {
        return pwd;
    }

    public static double getInterestRate() {
        return interestRate;
    }

    public static void setInterestRate(double interestRate) {
        Account.interestRate = interestRate;
    }

    public static double getMinMoney() {
        return minMoney;
    }

    public static void setMinMoney(double minMoney) {
        Account.minMoney = minMoney;
    }

    public int getId() {
        return id;
    }

    public double getBalance() {
        return balance;
    }

    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", pwd='" + pwd + '\'' +
                ", balance=" + balance +
                '}';
    }
}

package com.base.learn;

public class AccountTest {
    public static void main(String[] args) {
        Account acct1 = new Account();
        Account acct2 = new Account("1234qwer", 2000);

        Account.setInterestRate(0.012);
        Account.setMinMoney(100);

        System.out.println(acct1); // Account{id=1001, pwd='000000', balance=0.0}
        System.out.println(acct2); // Account{id=1002, pwd='1234qwer', balance=2000.0}

    }
}

2.3 静态代码块

链接后续补充

2.4 静态内部类

链接后续补充

参考:
https://zhuanlan.zhihu.com/p/259368621
https://blog.csdn.net/jiahao1186/article/details/121886704

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值