欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java中static修饰符你真的懂吗?

程序员文章站 2022-05-13 23:51:11
...

static在设计的时候留下了一个坑,这个坑啊,如果不是经常开发的伙伴,还不容易发现,但是这个坑说起来也简单,也就是内存上的问题。

首先来了解一下static的特点

1、static是一个修饰符,用于修饰l类成员。(成员变量,成员函数)static修饰的成员变量 称之为静态变量或类变量。

2、static修饰的成员被所有的对象共享。(记住是所有)

3、static优先于对象存在,因为static的成员随着类的加载就已经存在。(这一点可以参考静态代码块)

4、static修饰的成员需要使用类名调用,可以不用定义类的对象。(类名.静态成员)。

5、static修饰的数据是共享数据,对象中的存储的是特有的数据。

上面提到了类,那么就需要来讲述一下两个关于类的概念点:

1、实例对象:就是类被new了后的对象称为实例对象。
2、类对象:就是类中被static修饰的属性。属于类所拥有,可以称为静态属性 没有被声明为static的属性,就是属于实例的,也称为成员属性

那么问题就来了:成员变量和静态变量有什么区别?
区别如下:
1、生命周期的不同:******(重点)

成员变量随着对象的创建而存在随着对象的回收而释放。

静态变量随着类的加载而存在随着类的消失而消失。

2、调用方式不同:****(重点)

成员变量只能被对象调用。

静态变量可以被对象调用,也可以用类名调用。(推荐用类名调用)

3、别名不同:

成员变量也称为实例变量。

静态变量称为类变量。

4、数据存储位置不同:*****(重点的重点,坑所在)

成员变量数据存储在堆内存的对象中,所以也叫对象的特有数据。

静态变量数据存储在方法区(共享数据区)的静态区,所以也叫对象的共享数据。

为什么说第四点是坑所在呢?因为static的主要保证的就是内存方面的唯一,无论创建了多少个实例对象,内部的静态属性的地址都会是同一个,也就是说,你为每一个实例对象的静态属性都赋了值,但是,它所得到的值只会是最后一次所赋的值。
文字说明太枯燥,理论+实操=真理。
上代码:

import java.util.LinkedList;
import java.util.List;

public class Text {
	//定义一个存放对象的集合
    private static List<UserInformation> list=new LinkedList<UserInformation>();
    //集合内对象所需要的变量,使用数组存放
    private static final String[] word=new String[]{
            "张三","李四","王五","赵六","田七"
    };


    public static void main(String[] args) {
    	//初始化集合并为内部对象赋值
        for(int i=0;i<5;i++){
           UserInformation u=new UserInformation();
           u.setName(word[i]);
           list.add(u);
        }

		//打印内部成员的内存地址和属性保存的值
        for(int i=0;i<list.size();i++){
            System.out.println(list.get(i).toString()+"---->"+list.get(i).getName());
        }
    }
}


//集合中表示值的类
class UserInformation{
    private static String name;

    public void setName(String name){
       this.name=name;
    }

    public String getName(){
        return this.name;
    }
}

结果:

[email protected]>田七
[email protected]>田七
[email protected]>田七
[email protected]>田七
[email protected]>田七

按照以往,结果应该会是:

[email protected]>张三
[email protected]>李四
[email protected]>王五
[email protected]>赵六
[email protected]>田七

不过这里就意想不到了

这里拿引用类型来举例,基本数据类型也是一样的。

而且我特意连同实例对象的内存地址也打印了出来,就是为了显示是否最后会是同一个对象。
从结果可以看出来:

不同实例对象之间,是处于不同的内存地址,但是实例对象内部的静态属性却是同一个内存地址。


同时,static自身携带的小坑,也就是这个。

以往我们的开发都是以类为单位,只要实例对象不同,则内部的成员肯定不会有所关联,哪怕定义了static属性,因为我们忽略了static的这个特点,而导致程序没有达到自己的理想情况

我个人出现这个情况是在我自己玩JDBC的时候,开发一个功能,在类的内部使用到了static,然后程序没有报错且能正常运行,但是,却在需要使用到该功能的时候就出现了NullPointException,我找了两天都没找到问题,后来我把程序用的修饰符和其他有关联的知识都回忆了一边,才找到是static的问题。

所以说不能好高骛远。底层基础真的很重要,是真的能影响整个项目而又不会让开发者简单就发现的BUG点。

这里仅仅只是我个人的看法,不是特别全面,当中也可能存在错误,也希望大家多多指导,有则改之无则加勉。