JAVA_SE基础——34.static修饰成员变量
需求:描述一下学校的学生。 特点:都是中国人....
测试代码1:
class Student{ String name; String country = "中国"; //国籍 //构造函数 public Student(String name){ this.name = name; } } class Demo9 { public static void main(String[] args) { Student s1 = new Student("小红"); Student s2 = new Student("陈明"); System.out.println("姓名:"+s1.name+" 国籍:"+ s1.country); System.out.println("姓名:"+s2.name+" 国籍:"+ s2.country); } }
运行结果:
姓名: 小红 国籍: 中国
姓名: 陈明 国籍: 中国
这段代码能够运行,看似没有什么问题,那么我们再看下代码在内存中是怎么运行的?
测试代码1内存图:
s1和s2的对象都有个country="中国";
一两个的时候都没什么问题,但是学校,都是成千上万个的,每多一个学生,内存就多一个country="中国"; 所有学生的国籍都是中国的 ,都有公共的特点,所以就没必要在每个学生对象上面都加country="中国"; 这样会很耗内存的 。。
所以我们发现一个问题先
目前存在的问题: 所有的学生都是中国 的,有n个学生就会有n份中国的 数据存内存中,这样子
会浪费内存。
解决问题,内存优化
1:为了让所有Student对象都共享一个country?
可以尝试将country放入共享区。
2:country变量如何放入共享区?对象如何访问?
使用static
测试代码2:
class Student{ String name; static String country = "中国"; //国籍 //构造函数 public Student(String name){ this.name = name; } } class Demo9 { public static void main(String[] args) { Student s1 = new Student("小红"); Student s2 = new Student("陈明"); System.out.println("姓名:"+s1.name+" 国籍:"+ s1.country); System.out.println("姓名:"+s2.name+" 国籍:"+ s2.country); } }
运行结果:
姓名: 小红 国籍: 中国姓名: 陈明 国籍: 中国
测试代码1:和测试代码2:运行结果一样,而且在代码上貌似只加了static关键字,肯定有人会觉得这两段代码没区别
来看下测试代码2的内存图:
测试代码1:和测试代码2:内存图的区别是:静态的成员变量只会在数据共享区中维护一份,而非静态成员变量的数据会在每个对象中都维护一份的。。(有static的成员变量叫做静态成员变量。没有则叫非静态成员变量)
没static关键字:每new一个对象 ,都多一个conuntry="中国"
有static关键字:每new一个对象,都去调用数据共享区的country="中国"
使用了static修饰country,那么这时候country就是一个共享的数据。
测试代码3:
class Student{ String name; //使用了static修饰country,那么这时候country就是一个共享的数据。 static String country = "中国"; //国籍 //构造函数 public Student(String name){ this.name = name; } } class Demo9 { public static void main(String[] args) { Student s1 = new Student("小红"); Student s2 = new Student("陈明"); s1.country = "小日本"; System.out.println("姓名:"+s1.name+" 国籍:"+ s1.country); // 小日本 System.out.println("姓名:"+s2.name+" 国籍:"+ s2.country); // 小日本 } }运行结果:
姓名: 小红 国籍: 小日本
姓名: 陈明 国籍: 小日本
测试代码3内存图:
s1.country = "小日本";这行代码,把方法区的 country="中国" 给从新赋值了 所以此行代码后的所有new出来的Student对象。 国籍都是country="小日本"
测试代码4:
class Student{ String name; String country = "中国"; //国籍 //构造函数 public Student(String name){ this.name = name; } } class Demo9 { public static void main(String[] args) { Student s1 = new Student("小红"); Student s2 = new Student("陈明"); s1.country = "小日本"; System.out.println("姓名:"+s1.name+" 国籍:"+ s1.country); // 小日本 System.out.println("姓名:"+s2.name+" 国籍:"+ s2.country); // 中国 } }
运行结果:
姓名: 小红 国籍: 小日本
姓名: 陈明 国籍: 中国
测试代码4内存图:
这次没有加static关键字,所以每个对象自己单独有个country
s1.country = "小日本";
只是把s1所连接的对象里面的country赋值成"小日本" 了、
所以不影响s2所连接的对象。
下面我们来详细的学习一下static关键字
static是(静态\修饰符)
1. static修饰成员变量 :如果有数据需要被共享给所有对象使用时,那么就可以使用static修饰。
静态成员变量的访问方式:
方式1: 可以使用对象进行访问。
格式: 对象.变量名。
方式二: 可以使用类名进行访问。
格式: 类名.变量名;
注意:
1. 非静态的成员变量只能使用对象进行访问,不能使用类名进行访问。
2. 千万不要为了方便访问数据而使用static修饰成员变量,只有成员变量的数据是真正需要被共享的时候才使用static修饰。
static修饰成员变量的应用场景: 如果一个数据需要被所有对象共享使用的时候,这时候即可好实用static修饰。