Java基础篇(一)———浅谈静态关键词:Static

static关键字的作用
⚫ static是静态的意思,可以修饰成员变量和成员方法。
⚫ static修饰成员变量表示该成员变量只在内存中只存储一份,可以被共享访问、修改。

一、Static修饰成员变量

public class User {
// 成员变量
public static int onlineNumber= 161;
private String name;
private int age;
}

其中,onlineNumber就是static修饰的静态成员变量,对于静态成员变量,我们推荐采用    -》 类名.静态成员变量。的方式引用,原因我们在后面讲解。

而对于实例成员变量我们使用  -》 对象.静态成员变量。

那么两种变量定义方式的区别和使用途径有哪些呢?

⚫ 静态成员变量(有static修饰,属于类,内存中加载一次): 常表示如在线人数信息、等需要被共享的信息,可以被共享访问。
⚫ 实例成员变量(无static修饰,存在于每个对象中):常表示姓名name、年龄age、等属于每个对象的信息。

 

关于 static修饰成员变量的内存原理的解释

 1 package com.guleng985.staticDemo;
 2 
 3 public class User {
 4     public static int onlineNumber ;
 5     private String name ;
 6     private int age;
 7 
 8     public static void main(String[] args) {
 9         System.out.println(User.onlineNumber);
10         onlineNumber++;
11         System.out.println(onlineNumber);
12 
13         // System.out.println(name);会报错,因为没定义对象
14         User u1 = new User();
15         u1.name = "孙悟空";
16         u1.age = 21;
17         u1.onlineNumber ++;//不推荐
18         System.out.println(onlineNumber);
19         System.out.println(u1.name);
20         System.out.println(u1.age);
21     }
22 }

运行结果如下:

0
1
2
孙悟空
21

在开始编译Use.class文件在方法区时,静态成员变量也会被同时加载(存放在堆内存中),而实例成员变量是属于每个对象的,在没有new一个对象的时候,实例成员变量

是不会加载的。

我们可以看到运行结果最先输出的onlineNumber的值为0,是因为成员变量默认为0,需要注意的是为什么第11行的onlineNumber可以直接写成员变量,原因是他们在同一个类中,可以进行访问。

再看到第17行,接下来我们开始解释不推荐使用此方法访问的原因:

该方法访问是利用创建的一个新的对象的地址去指向堆内存中的静态成员变量onlineNumber来间接访问静态变量,在需要进行大量运算时效率低,需要开辟的内存也增多了。

二、Static修饰方法

成员方法的分类:
⚫ 静态成员方法(有static修饰,属于类),建议用类名访问,也可以用对象访问。
⚫ 实例成员方法(无static修饰,属于对象),只能用对象触发访问。

package com.guleng985.staticDemo;

public class Student {
    private String name;

    /**
     * 实例方法,需要访问对象来访问该方法
     */
    public void study(){
        System.out.println(name);
    }
    /**
     * 静态方法,有static修饰,属于类
     */
    public static void getMax(int a,int b){
        System.out.println(a > b ? a : b);
    }

    public static void main(String[] args) {
        getMax(10,20);
        Student st = new Student();
        st.name = "小芳";
        st.study();
      //study();报错
  } }

运行结果如下:

20

小芳

静态成员方法的内存原理与静态成员变量类似,不过静态方法属于类和对象共享,所以在刚开始加载类时,静态方法的访问入口也会同步提供到方法区,而不是堆内存。

 

为了更好地理解静态方法,我们引入了工具类:
⚫ 工具类中定义的都是一些静态方法,每个方法都是以完成一个共用的功能为目的。

 

现状问题分析:
⚫ 如果登录和注册等多处地方都存在验证码逻辑,就会导致同一个功能多处开发,会出现代码重复度过高。

 1 package com.guleng985.verifyTool;
 2 
 3 import java.util.Random;
 4 
 5 public class Verify {
 6     /**
 7      * 私有化构造器
 8      */
 9     private Verify(){}
10     public static String vrCode(int n){
11         String rd = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
12         Random r = new Random();
13         String code = "";
14         for (int i = 0; i < n; i++) {
15             int index = r.nextInt(rd.length());
16             code += rd.charAt(index);
17         }
18         return code;
19     }
20 }

这样,我们就可以直接调用了。其中私有化构造器是因为静态方法调用本来就不需要创建对象,私有化可以减少内存的浪费。
工具类的好处
⚫ 一是调用方便,二是提高了代码复用(一次编写,处处可用)
为什么工具类中的方法不用实例方法做?
⚫ 实例方法需要创建对象调用,此时用对象只是为了调用方法,这样只会浪费内存。
工具类的定义注意
⚫ 建议将工具类的构造器进行私有,工具类无需创建对象。
⚫ 里面都是静态方法,直接用类名访问即可。

static访问注意实现:
⚫ 静态方法只能访问静态的成员,不可以直接访问实例成员。
⚫ 实例方法可以访问静态的成员,也可以访问实例成员。
⚫ 静态方法中是不可以出现this关键字的。

this是调用对象,而静态方法可以是对象也可以是类调用,两者冲突,所以不能调用

而实例方法必须要创建对象,正好符合this的调性。

实例成员方法直接访问实例成员变量 可以(都属于对象)
实例成员方法直接访问静态成员变量 可以(静态成员可以共享)
静态成员方法直接访问实例成员变量 不可以(实例变量属于对象,但可以创建对象来访问)
静态成员方法直接访问静态成员变量 可以(都属于类)
posted @ 2022-02-20 23:48  Object_gl  阅读(91)  评论(0)    收藏  举报