Saul's blog Saul's blog
首页
后端
分布式
前端
更多
分类
标签
归档
友情链接
关于
GitHub (opens new window)

Saul.J.Wu

立身之本,不在高低。
首页
后端
分布式
前端
更多
分类
标签
归档
友情链接
关于
GitHub (opens new window)
  • Java入门基础

    • 计算机常识

    • Java语言概述

    • 基本语法

    • 数组

    • 面向对象

      • 面向对象
      • 类和对象
      • 类的成员-属性
      • 类的成员-方法
      • 类的成员-构造器
      • 面向对象特性-封装
      • this关键字
      • package关键字
      • import关键字
      • 面向对象特征-继承
      • 方法的重写
      • 访问权限修饰符
      • super关键字
      • 子类对象实例化的全过程
      • 面向对象特征-多态
      • 强制类型转换
      • Object类
      • 包装类
      • static关键字
        • 前言
        • 类属性、类方法的设计思想
        • 静态属性
          • 内存解析
        • 静态方法
        • 判断使用场景
      • 单例设计模式
      • main方法
      • 类的成员-代码块
      • final关键字
      • 抽象类与抽象方法
      • 接口
      • 类的成员-内部类
    • 异常处理

  • Java核心基础

  • 设计模式

  • Web开发

  • SpringBoot

  • 微服务

  • Elasticsearch

  • 运维

  • 后端
  • Java入门基础
  • 面向对象
SaulJWu
2020-12-15

static关键字

# 前言

当我们编写一个类时,其实就是在描述其对象的属性和行为,而并没有产生实质上的对象,只有通过new关键字才会产生出对象,这时系统才会分配内存空间给对象,其方法才可以供外部调用。

我们有时候希望无论是否产生了对象或无论产生了多少对象的情况下,某些特定的数据在内存空间里只有一份,例如所有的中国人都有个国家名称,每一个中国人都共享这个国家名称,不必在每一个中国人的实例对象中都单独分配一个用于代表国家名称的变量。

public class Circle {
    private double radius;

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

    private double getArea() {
        return Math.PI * this.radius * this.radius;
    }

    public double getRadius() {
        return radius;
    }

    public void setRadius(double radius) {
        this.radius = radius;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

创建两个对象:

Circle c1 = new Circle(2.0);
Circle c2 = new Circle(3.0);
1
2

Circle类中的变量radius是一个实例变量(instance variable),它属于类的每一个对象,不能被同一个类的不同对象所共享。

两个对象存储在不同的空间,相互独立,不受影响。

# 类属性、类方法的设计思想

类属性作为该类各个对象之间共享的变量。在设计类时,分析哪些属性不因对象的不同而改变,将这些属性设置为类属性。相应的方法设置为类方法。

如果方法与调用者无关,则这样的方法通常被声明为类方法,由于不需要创建对象就可以调用类方法,从而简化了方法的调用。

使用范围:

在Java类中,可用static修饰属性、方法、代码块、内部类。

被修饰后的成员具备以下特点:

  • 随着类的加载而加载
  • 优先于对象存在
  • 修饰的成员,被所有对象所共享
  • 访问权限允许时,可不创建对象,直接被类调用

# 静态属性

在一个类中,类的属性是可以用static来修饰,如果使用了static修饰,那么此类变量称为静态属性(或类变量),没有使用static的属性称为非静态属性(实例变量)。

**实例变量:**就是以前我们写类的属性,随着对象的实例而创建,每个对象的属性都独立存储在独立的堆空间中。每个对象的属性都是独立的,不会影响其他对象的属性。

**静态属性:****随着类的加载而加载。**多个对象共享同一个静态变量。当通过某一个对象修改静态变量时,其他对象再去访问此静态变量时,发现已经是修改过的。静态属性可以称为类变量。

其他说明:

  • 静态属性和实例变量的访问方式并无区别。可以通过"类名.静态属性名"
  • 静态属性随着类的加载而加载。
  • 由于类只会加载一次,则静态变量在内存中也只会存一份,存在方法区的静态域中。

类变量(类属性)由该类的所有实例共享

public class Person {
    public static int total = 0;

    private int id;

    public Person() {
        total++;
        id = total;
    }

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                '}';
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@Test
public void test1() {
    Person p1 = new Person();
    Person p2 = new Person();
    System.out.println(p1);
    System.out.println(p2);
}
1
2
3
4
5
6
7
Person{id=1}
Person{id=2}
1
2

# 内存解析

image-20201215113432594

其中name是string类型,实际上也是在常量池中,不过还没讲到,这个可以暂时忽略。

# 静态方法

使用了static关键字修饰的方法就叫静态方法。

  • 静态方法跟静态属性一样,都是随着类的加载而加载。
  • 直接类名.静态方法名调用或者对象.静态方法名
  • 在static方法内部只能访问类的static修饰的属性或方法,不能访问类的非static的结构。
    • 非静态方法既可以调用非静态方法或者属性,也可以调用静态的方法或者属性。
  • 在静态方法内不能使用this和super关键字,因为这两个关键字都基于有对象之后才能使用。

类内部调用静态属性,其实已经省略了类名

public class Person {
    public static int total = 0;

    private int id;

    public Person() {
        total++;
        id = total;
        //id = Person.total;
    }

}
1
2
3
4
5
6
7
8
9
10
11
12

# 判断使用场景

开发中,如何确定一个属性是否要声明为static?

属性是可以被多个对象共享的,不会随着对象不同而不同的。

开发中,如何确定一个方法是否要声明为static?

  • 操作静态属性的方法通常设计为静态方法。
  • 工具类中的方法,习惯上声明为static,比如Math、Arrays、Collections
帮我改善此页面 (opens new window)
#static#静态属性#静态方法
上次更新: 2020/12/18, 12:50:58
包装类
单例设计模式

← 包装类 单例设计模式→

最近更新
01
zabbix学习笔记二
02-28
02
zabbix学习笔记一
02-10
03
Linux访问不了github
12-08
更多文章>
Theme by Vdoing | Copyright © 2020-2022 Saul.J.Wu | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式