首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >关于static关键字,我讲两句

关于static关键字,我讲两句

作者头像
知否技术
发布2021-12-02 08:13:39
2530
发布2021-12-02 08:13:39
举报
文章被收录于专栏:eclipse编程eclipse编程eclipse编程

1. 什么是 static

先用词典查一下意思:

在 java 语言中,static 是一个关键字,表示“静态的”。它可以用来修饰变量、方法、代码块等。

static 修饰的变量叫静态变量,修饰的方法叫静态方法,修饰的代码块叫静态代码块

在 java 中凡是被 static 修饰的东西都跟类有关,跟对象没一毛钱关系,不需要对象的参与。

被 static 修饰的东西可以直接用 类名. 进行访问。

2. 为什么要用 static

先看一个例子:

  1. 新建诗人类
//诗人类
public class Poet {
    // 姓名
    private String name;
    // 年龄
    private int age;
    // 朝代
    private String dynasty;

    public Poet(String name, int age, String dynasty) {
        this.name = name;
        this.age = age;
        this.dynasty = dynasty;
    }
    
    @Override
    public String toString() {
        return "姓名:" + this.name + ", 年龄:" + age + ", 朝代:" + dynasty;
    }
}
  1. 测试
// 静态方法测试
public class StaticTest {
  public static void main(String[] args) {
      Poet poet1 = new Poet("李白",61,"唐朝");
      Poet poet2 = new Poet("杜甫",50,"唐朝");
      System.out.println(poet1.toString());
      System.out.println(poet2.toString());
  }
}
  1. 运行结果:

结果分析:

上面的例子中我们新建了两个诗人对象:李白和杜甫,他们都是唐朝伟大的诗人。

java 程序运行时, JVM 内存图中是这样展示的:

我们知道李白和杜甫所处的朝代都是唐朝,如果再创建白居易、杜牧、孟浩然等一堆诗人对象,我们是不是还要在堆里面为他们各自开辟个内存,用来存储同一个朝代信息?这样是不是太浪费内存了?

String dynasty = "唐朝";

所以 static 的出现,可以帮助我们处理相同数据共享的问题。

3. static 的几种用法

3.1 静态变量

3.1.1 变量分类

在 java 中变量分为局部变量和成员变量。

局部变量在方法体中定义,例如:

 public void eat(){
        String food = "苹果";
        System.out.println(food);
    }

成员变量又分为实例变量和静态变量,例如:

//诗人类
public class Poet {
    // 实例变量:姓名
    private String name;
    // 实例变量:年龄
    private int age;
    // 静态变量:朝代
    static String dynasty;
}
3.1.2 静态变量

被 static 修饰的变量叫做静态变量,没有被 static 修饰的变量叫做实例变量。

要想访问实例变量必须先创建对象,然后通过对象.变量名访问。因为实例变量对每个对象来说都是独一无二的,比如诗人对象的姓名、年龄等。

访问静态变量不需要创建对象,可以通过类名.变量名访问,例如:

//诗人类
public class Poet {
    // 实例变量:姓名
    private String name;
    // 实例变量:年龄
    private int age;
    // 静态变量:朝代
    static String dynasty = "唐朝";
}
// static测试类
public class StaticTest {
    public static void main(String[] args) {
        System.out.println(Poet.dynasty);
    }
}

运行结果:

我们都知道实例变量存储在堆内存中,通过调用构造方法进行初始化,例如:

而静态变量存储在方法区中,在类加载时初始化。静态变量在 JVM 内存图中是这样的:

所以当一个类中的所有对象的某一些属性值一样的时候,我们可以设置成静态变量,从而实现数据共享。

总结:

  • 1. 静态变量存在于JVM的方法区中
  • 2. 静态变量可以通过类名.变量名访问,和对象无关
  • 3. 当类中对象的一些属性值一样的时候(不会随着对象的改变而改变),我们可以设置成静态的。

3.2 静态代码块

3.2.1 定义静态代码块

语法格式:

类{
  // 静态代码块
  static{
    代码
  }  
}

例如:

public class StaticTest {
    static {
        System.out.println("李白和杜甫是我国伟大的诗人,李白比杜甫大11岁");
    }
    public static void main(String[] args) {
        System.out.println("哈哈哈哈");
    }
}

运行结果:

静态代码块在类加载时执行,并且只执行一次。也就是说只要类一加载,这玩意就出来了。

所以上面的例子会先打印静态代码块中的数据。

3.2.2 多个静态代码块

一个类中可以编写多个静态代码块,他们按照从上到下的顺序去执行,例如:

public class StaticTest {
    static {
        System.out.println("床前明月光");
    }
    static {
        System.out.println("疑是地上霜");
    }
    static {
        System.out.println("举头望明月");
    }
    static {
        System.out.println("低头思故乡");
    }
    public static void main(String[] args) {
        System.out.println("李白代表作《静夜思》");
    }
}

运行结果:

3.2.3 静态代码块使用场景

因为静态代码块在类加载时执行,并且只执行一次,所以我们可以在初始化一些数据的时候使用静态代码块。例如:

  • 1. 给对象的属性初始化
  • 2. jdbc 加载驱动

3.3 静态方法

3.3.1 语法格式

static 修饰的方法叫做静态方法。语法格式:

修饰符 static 返回值 方法名(){

}

例如:

public class StaticTest {
    public static void eat(){
        System.out.println("-----");
    }
}
3.3.2 使用场景

因为静态方法随着类的加载而加载,跟对象无关,所以我们可以把一些通用的辅助功能定义成静态方法。

例如我们在写工具类的时候就可以使用静态方法:

// 计算工具类
public class ComputeUtil {

    public static int add(int a, int b) {
        return a + b;
    }

    public static int sub(int a, int b) {
        return a - b;
    }

    public static void main(String[] args) {
        int addResult = ComputeUtil.add(1, 2);
        System.out.println("两数相加结果:"+addResult);
        int subResult = ComputeUtil.sub(10, 2);
        System.out.println("两数相减结果:"+subResult);
    }
}

运行结果:

4. 关于 static 的几个小问题

4.1 静态方法中可以使用 this 关键字吗?例如:

//诗人类
public class Poet {
    // 实例变量:姓名
    private String name;
    // 静态变量:朝代
    static String dynasty = "唐朝";
    static void initName(){
        this.name = "李白";
    }
}

回答:不可以。静态代码随着类的加载而加载,this 表示当前对象,因为类加载的时候还没创建对象呢,所以不能用。

4.2 静态方法可以使用静态变量吗?例如:

//诗人类
public class Poet {
    // 实例变量:姓名
    private String name;
    // 静态变量:朝代
    static String dynasty ;
    
    static void init(){
        dynasty = "唐朝";
    }
}

回答:可以,因为他俩都是随着类的加载而加载。

4.3 静态方法可以调用非静态方法吗?例如:

public class Poet {
    
    static void init(){
        write();
    }

    void write(){
        System.out.println("写首诗");
    }
}

回答:不可以。静态方法是属于类的,即静态方法是随着类的加载而加载的,在加载类时,程序就会为静态方法分配内存。非静态方法是属于对象的,对象是在类加载之后创建的,也就是说静态方法先于对象存在,这时候还没有创建对象,所以不能。

4.4 静态方法可以使用非静态变量吗?例如:

//诗人类
public class Poet {
    // 姓名
    private String name;
    static void init(){
       name = "李白";
    }
}

回答:不可以。因为非静态变量是实例变量,只有创建对象之后才能使用。而静态方法随着类的加载而加载,这时候还没有创建对象,所以不能。

4.5 非静态方法可以使用静态变量吗?例如:

//诗人类
public class Poet {
    // 姓名
    static String name;
    void init(){
       name = "李白";
    }
}

回答:可以。因为先有静态变量,后有非静态方法。后面出来的肯定可以访问前面出来的。

4.6 非静态方法可以调用静态方法吗?

回答:可以。同上。

总结:static 是属于类级别的,随着类的加载而加载,先于对象相关的东西出现。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-12-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 知否技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 什么是 static
  • 2. 为什么要用 static
  • 3. static 的几种用法
    • 3.1 静态变量
      • 3.1.1 变量分类
      • 3.1.2 静态变量
    • 3.2 静态代码块
      • 3.2.1 定义静态代码块
      • 3.2.2 多个静态代码块
      • 3.2.3 静态代码块使用场景
    • 3.3 静态方法
      • 3.3.1 语法格式
      • 3.3.2 使用场景
  • 4. 关于 static 的几个小问题
    • 4.1 静态方法中可以使用 this 关键字吗?例如:
      • 4.2 静态方法可以使用静态变量吗?例如:
        • 4.3 静态方法可以调用非静态方法吗?例如:
          • 4.4 静态方法可以使用非静态变量吗?例如:
            • 4.5 非静态方法可以使用静态变量吗?例如:
              • 4.6 非静态方法可以调用静态方法吗?
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档