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

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;
    }
}

结果:

connection.UserInformation@5b480cf9---->田七
connection.UserInformation@3941a79c---->田七
connection.UserInformation@506e1b77---->田七
connection.UserInformation@4fca772d---->田七
connection.UserInformation@9807454---->田七

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

connection.UserInformation@5b480cf9---->张三
connection.UserInformation@3941a79c---->李四
connection.UserInformation@506e1b77---->王五
connection.UserInformation@4fca772d---->赵六
connection.UserInformation@9807454---->田七

不过这里就意想不到了

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

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

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


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

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

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

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

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

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值