5.5static(修饰和初始化顺序)

1stati关键字

作用:static是做修饰用的,可以修饰属性,方法,代码块

static修饰的属性是静态属性,在类中是共用的(全局变量)

static修饰的函数和属性在类加载后可以自己调用,可以不用new来实例对象

★建议用类名来调用


1.1声明方法

只要在变量前加上这个关键字就行,例:

	static int a = 3;     //在变量类型前加static就行
函数也一样,例如main方法:
public static void main(String[] args) {	//在返回值类型前加static

1.2调用函数和属性(建议用类名来调用)

例:Animal类

class Animal{
	static String name;			//用static修饰属性
	public static void show(){		//static修饰函数
		System.out.println("我是一只小"+name);
	}
}

main入口:

	public static void main(String[] args) {
		//这里面可以不用new实例化类
		//直接用类名调用,方法如下
		Animal.name = "灰熊";
		Animal.show();		//输出:小灰熊
		}
这样一眼看过去就知道是用static修饰的属性和方法


1.3static的内存模型

staic修饰的属性在内存中存放的与之前的不样,看代码:animal类,增加了int属性,show也不是staic的

class Animal{
	int age;
	static String name;			//用static修饰属性
	public void show(){		
		System.out.println("我是一只"+age+"岁的小"+name);
	}
}
修改的main方法:
	public static void main(String[] args) {
		//第一只熊
		Animal a = new Animal();
		a.name = "灰熊";
		a.age = 20;
		//第二只熊,棕色的
		Animal a2 = new Animal();
		a2.name = "棕熊";
		a2.age = 30;
		a.show();	//输出:我是一只20岁的小棕熊
		a2.show();	//输出:我是一只30岁的小棕熊
	}

这里输出的都是棕熊,但年龄有不一样,为什么呢?熊a不应该是灰色的吗?

看内存:

解析:

1,当类中有staic关键字修饰的属性时,JVM会在堆的datasegenmt(就叫常量堆吧)中专门为该类分配一块内存,将staic修饰的name放在该内存中,而不是放在堆中(如图右下所示)

2,当执行到a.age=20时,就会去堆中找age,找到age就等于20

3,执行下一句a.name = 灰熊时,会先在堆中找,没找到就会在常量堆中找,找到name,name=灰熊

3,当执行到a2.anme = 棕熊时,它会到自己的堆中找name属性,没找到是就会到常量堆中找name,这时”name=灰熊“就会改成”name=棕熊“。a和a2是共用这块内存的。所以导致最后输出的结果不理想


2初始化顺序

先初始化static修饰的属性

再初始化属性

最后初始化构造方法

★*static修饰的属性仅仅只会初始化一次

看栗子:school类

class School{
	//实例化一个Student,第一个
	Student s = new Student(1);				//6,输出:student 1
	
	//带参数的构造方法
	public School(int i){					//7,输出:school 1
		System.out.println("school "+i);	
	}
	
	//static属性
	static Student s2 = new Student(2);		//3,这是三,输出:student 2
	
}
student类:
class Student{
	//第一个属性
	Study sd = new Study(1);		//1,输出:Study1
						//4,这是第二轮:Study1
	//构造方法
	public Student(int i){
		System.out.println("student "+i);
	}
	
	//第二个属性
	Study sd2 = new Study(2);		//2,输出:Study2
						//5,这是第二轮:Study2
}

增加的study类:

class Study{
	//构造方法
	public Study(int i){
		System.out.println("Study"+i);
	}
}
main入口:
	public static void main(String[] args) {
		School s=  new School(1);
	}
输出顺序是:

Study1
Study2
student 2
Study1
Study2
student 1
school 1

为什么student2在student1前面呢?应为是在school类中将第二个属性改为static。

解析:

1,从main方法进,执行到new School(1),然后进入school类

2,注意了,这里的第二个属性用了static修饰,所以会先初始staic关键字修饰的属性,所以先new Student(2),进入student类

3,student类中的属性都没用static修饰,所以先初始化第一个属性new study(1),进入study类

4,study类中没有属性,直接初始化构造函数,输出:Study1,回到student

5,student类中在初始化第二个属性,new study(2),进入study类

6,study类中没有属性,直接初始化构造函数,输出:Study2,回到student

7,student类中没有未初始的属性,就会初始化构造函数,输出:student 2。student执行完了,回到school

8,school中在初始化第一个属性new student(1),进入student类,

9,重复第3,4,5,6,7。只是第7步中传入的参数是1,所以输出:student 1。然后回到school

10,school中两个属性都初始化完了,就会初始化构造函数,输出school1,回到main,然后结束。


3static修饰的属性只会初始化一次

看栗子:修改student中代码,将它的第一个属性改为static

class Student{
	//第一个属性,现在用了static修饰
	static Study sd = new Study(1);		//1,输出:Study1
						//*注意的是这一轮已经不会初始化了  它只会初始化一次,所以没有了(4,这是第二轮:Study1)
	//构造方法
	public Student(int i){
		System.out.println("student "+i);
	}
	
	//第二个属性
	Study sd2 = new Study(2);		//2,输出:Study2
						//5,这是第二轮:Study2
}

输出结果:

Study1
Study2
student 2
Study2
student 1
school 1
对比之前,这里的第二轮里少了Study1,因为用static修饰了sd,所以执行到第二轮是他就不会再初始化了


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值