JavaSE基础第九章(static、this和super)

一、static

1、概述

static 是 java语言中的关键字,表示“静态的”,它可以用来修饰变量、方法、代码块等,修饰的变量叫做静态变量,修饰的方法叫做静态方法,修饰的代码块叫做静态代码块。在 java 语言中凡是用 static 修饰的都是类相关的,不需要创建对象,直接通过“类名”即可访问,即使使用“引用”去访问,在运行的时候也和堆内存当中的对象无关。

2、静态变量

Java中变量包括:局部变量和成员变量,在方法体中声明的变量为局部变量,有效范围
很小,只能在方法体中访问,方法结束之后局部变量内存就释放了,在内存方面局部变量存储在栈当中。
在类体中定义的变量为成员变量,而成员变量又包括实例变量和静态变量,当成员变量声明时使用了 static 关键字,那么这种变量称为静态变量,没有使用 static 关键字称为实例变量,实例变量是对象级别的,每个对象的实例变量值可能不同,所以实例变量必须先创建对象,通过“引用”去访问,而静态变量访问时不需要创建对象,直接通过“类名”访问。实例变量存储在堆内存当中,静态变量存储在方法区当中。实例变量在构造方法执行过程中初始 化,静态变量在类加载时初始化。
静态变量和静态方法比较正式的方式是直接采用“类名”访问,但实际上使用“引用”也可以访问,并且空引用访问静态变量和静态方法并不会出现空指针异 常。实际上,在开发中并不建议使用“引用”去访问静态相关的成员,因为这样会让程序员困 惑,因为采用“引用”方式访问的时候,程序员会认为你访问的是实例相关的成员。
总之,所有实例相关的,包括实例变量和实例方法,必须先创建对象,然后通过“引用”的方式去访问,如果空引用访问实例相关的成员,必然会出现空指针异常。所有静态相关的,包括静态变量和静态方法,直接使用“类名”去访问。虽然静态相关的成员也能使用“引用” 去访问,但这种方式并不被主张。

3、静态代码块

静态代码块的语法格式:

{
	//静态代码块 
	static{ 
		java语句;
	} 
}

静态代码块在类加载时执行,并且只执行一次。开发中使用不多,但离了它有的时候还真
是没法写代码。静态代码块实际上是 java 语言为程序员准备的一个特殊的时刻,这个时刻就 是类加载时刻,如果你想在类加载的时候执行一段代码,那么这段代码就有的放矢了。例如我 们要在类加载的时候解析某个文件,并且要求该文件只解析一次,那么此时就可以把解析该文 件的代码写到静态代码块当中了。

4、静态方法

方法在什么情况下会声明为静态的呢?方法实际上描述的是行为动作,我认为当某个动作在触发的时候需要对象的参与,这个方法应该定义为实例方法,例如:每个玩篮球的人都会打篮球,但是你打篮球和科比打篮球最终的效果是不一样的,显然打篮球这个动作存在对象差异化,该方法应该定义为实例方法。再如:每个高中生都有考试的行为,但是你考试和学霸考试最终的结果是不一样的,一个上了“家里蹲大学”,一个上了“清华大学”,显然这个动作也 是需要对象参与才能完成的,所以考试这个方法应该定义为实例方法。
以上描述是从设计思想角度出发来进行选择,其实也可以从代码的角度来进行判断,当方法体中需要直接访问当前对象的实例变量或者实例方法的时候,该方法必须定义为实例方法, 因为只有实例方法中才有this,静态方法中不存在 this。
在实际的开发中,“工具类”当中的方法一般定义为静态方法,因为工具类就是为了方便大家的使用,将方法定义为静态方法,比较方便调用,不需要创建对象,直接使用类名 就可以访问。

二、this

1、this是什么

this 是 java语言中的一个关键字,它存储在内存的什么地方呢,先看一段代码:

public class Customer { 
	private String name;
	public Customer(){ 
	} 
	public Customer(String _name){ 
		name = _name;
	} 
	public void setName(String _name){ 
		name = _name;
	} 
	public String getName(){ 
		return name;
	}
	public class CustomerTest { 
		public static void main(String[] args){ 
			Customer jack = new Customer("jack"); 	
			Customer rose = new Customer("rose");
		}
	}
}

以上程序的内存结构图如下所示:
在这里插入图片描述
this 可以看做一个变量,它是一个引用,存储在 Java 虚拟机堆内存的对象内部,this 这个引用保存了当前对象的内存地址指向自身,任何一个堆内存的 java对象都有一个 this,也就是 说创建100 个 java对象则分别对应100 个 this。通过以上的内存图,可以看出“jack引用”保存的内存地址是0x1111,对应的“this 引用”保存的内存地址也是 0x1111,所以“jack引用” 和“this引用”是可以划等号的。也就是说访问对象的时候 jack.name 和 this.name 是一样的, 都是访问该引用所指向对象的name 属性。
this 指向“当前对象”,也可以说 this 代表“当前对象”,this可以使用在实例方法中以及构造方法中,语法格式分别为“this.”和“this(…)”。this不能出现在带有 static的方法当中。

2、this使用在实例方法中

this 可以使用在实例方法当中,它指向当前正在执行这个动作的对象。实例变量正规的访问方式是采用“引用.”去访问,一般在实例方法中可以 直接访问当前对象的实例变量,而“this.”是可以省略的。
this 不能出现在 static 的方法中,可以出现在实例方法中,代表当前对象,大部分情况下 this 都是可以省略的,只有当在实例方法中区分局部变量和实例变量的时候不能省略。
在 static 的方法中不能直接访问实例变量,要访问实例变量必须先自己创建一个对象,通过“引用”可以去访问,不能通过 this 访问,因为在 static 方 法中是不能存在 this 的。其实这种设计也是有道理的,因为 static 的方法在执行的时候是 采用“类名”去调用,没有对象的参与,自然也不会存在当前对象,所以 static 的方法执 行过程中不存在 this。
总结:this不能使用在 static 的方法中,可以使用在实例方法中,代表当前对象,多数情况下this 是可以省略不写的,但是在区分局部变量 和实例变量的时候不能省略,在实例方法中可以直接访问当前对象实例变量以及实例方 法,在 static 方法中无法直接访问实例变量和实例方法。

3、this 使用在构造方法中

this还有另外一种用法,使用在构造方法第一行(只能出现在第一行,这是规定,记住就行),通过当前构造方法调用本类当中其它的构造方法,其目的是为了代码复用。调用时的语 法格式是:this(实际参数列表),有时候无参数构造方法中的代码和有参数构造方法中的代码一样,这个时候就可以在无参数构造方法中使用“this(实际参 数列表);”来调用有参数的构造方法,这样就可以让代码得到复用了。

super

1、super概述

super 和 this 可以对比着学习:
① this
this 是一个引用,保存内存地址指向自己。
 this 出现在实例方法中,谁调用这个实例方法,this就代表谁,this代表当前正在执行这个动作的对象。
 this 不能出现在静态方法中。
 this 大部分情况下可以省略,在方法中区分实例变量和局部变量的时候不能省略。
 “this(实际参数列表)”出现在构造方法第一行,通过当前的构造方法去调用 本类当中其它的构造方法。
② super
 严格来说,super 其实并不是一个引用,它只是一个关键字,super代表了当前对象中从父类继承过来的那部分特征。this 指向一个独立的对象,super 并不是指向某个“独立”的对象,假设张大明是父亲,张小明是儿子,有这样一句 话:大家都说张小明的眼睛、鼻子和父亲的很像。那么也就是说儿子继承了父 亲的眼睛和鼻子特征,那么眼睛和鼻子肯定最终还是长在儿子的身上。假设this 指向张小明,那么 super 就代表张小明身上的眼睛和鼻子。换句话说 super 其 实是 this的一部分。如下图所示:张大明和张小明其实是两个独立的对象,两 个对象内存方面没有联系,super 只是代表张小明对象身上的眼睛和鼻子,因 为这个是从父类中继承过来的,在内存方面使用了super 关键字进行了标记, 对于下图来说“this.眼睛”和“super.眼睛”都是访问的同一块内存空间。
 super 和 this 都可以使用在实例方法当中。
 super 不能使用在静态方法当中,因为super 代表了当前对象上的父类型特征, 静态方法中没有 this,肯定也是不能使用 super的。
 super 也有这种用法:“super(实际参数列表);”,这种用法是通过当前的构造 方法调用父类的构造方法。

super 使用在构造方法中,语法格式为:super(实际参数列表),这行代码和“this(实际参数列表)”都是只允许出现在构造方法第一行(这一点记住就行了),所以这两行代码是无法共 存的。“super(实际参数列表)”这种语法表示子类构造方法执行过程中调用父类的构造方法。

2、super使用在构造方法中

super 使用在构造方法中,语法格式为:super(实际参数列表),这行代码和“this(实际参数列表)”都是只允许出现在构造方法第一行(这一点记住就行了),所以这两行代码是无法共 存的。“super(实际参数列表)”这种语法表示子类构造方法执行过程中调用父类的构造方法。看以下两段地代码:

//父类构造方法
public People(String idCard,String name,boolean sex){ 
	this.idCard = idCard; 
	this.name = name; 
	this.sex = sex;
}
//子类的构造方法
public Student(String idCard,String name,boolean sex,int sno){ 
	this.idCard = idCard; 
	this.name = name; 
	this.sex = sex; 
	this.sno = sno;
}

子类的构造方法前三行和父类的一样,修改一下:

public Student(String idCard,String name,boolean sex,int sno){ 	
	super(idCard,name,sex); 
	this.sno = sno;
}

“super(实际参数列表);”语法表示调用父类的构造方法,代码复用性增强了,另外一方面也是模拟现实世界当中的“要想有儿子,必须先有父亲”的道理。不过这里的“super(实际参数列表)”在调用父类构造方法的时候,从本质上来说并不是创建一个“独 立的父类对象”,而是为了完成当前对象的父类型特征的初始化操作。(或者说通过子类的构 造方法调用父类的构造方法,是为了让张小明身上长出具有他父亲特点的鼻子和眼睛,鼻子和 眼睛初始化完毕之后,具有父亲的特点,但最终还是长在张小明的身上)。
当一个构造方法第一行没有显示的调用“super(实际参数列表)”的话,系统默认调用父类的无参数构造方法“super()”。当然前提是“this(实际参数列表)”也没有显示的去调用(因为 super()和 this()都只能出现在构造方法第一行,所以不能并存)。

通过以上内容的学习,还可以得出这样的结论:在 java语言当中无论是创建哪个java 对象,老祖宗Object 类中的无参数构造方法是必然执行的。

3、super使用在实例方法中

super 和 this 都可以使用在实例方法中,并且都不能使用在静态方法当中,“this”大部分情况下都是可以省略的,只有在方法中区分局部变量和实例变量的时候不能省略。那“super” 什么时候可以省略,什么时候不能省略呢?
父类和子类中有同名实例变量或者有同名的实例方法,想在子类中访问父类中的实例变量或实例方法,则super 是不能省略的,其它情况都可以省略。

总结

本章需要掌握Java中三个关键字的用法,一个是static、一个是this,一个是super。其中this要理解的是 this 是什么,内存中存储在哪里,要掌握 this在实例方法和构造方法中的用法。对于 static 来说,要理解 static 代表什么含义,要掌握静态变量、静态代码块、静态方法的使用。理解 super代表什么,主要掌握 super关键字的用法,例如在实例方法中 super 怎么用,在构造方法中 super 又应该怎么用。super 和 this 可以对比学习。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值