java中的this关键字

下一篇持续更新中… 如有错误欢迎指正!!!

文章目录

  • 1.使用规则
    • 测试一下
  • 2. this什么情况下不省?
    • 测试一下
  • 3.this可以用在哪里?
    • 测试一下
  • 练习题 1 :
    • 题 1 答案:
  • 附篇

1.使用规则

  1. this是一个关键字,翻译为:“ 这个 ”
  2. this是一个引用,this是一个变量。this变量中保存了内存地址,指向了自身。this存储在堆内存Java对象内部
  3. 创建100个Java对象,每一个对象都有this,也就是说有100个不同的this。
  4. this可以出现在 “ 实例方法 ” 当中,this指向当前正在执行这个动作的对象。(this代表当前对象)
  5. this在多数情况下都是可以省略不写的
  6. this不能使用在带有static的方法当中
public class Customer{
	
	//姓名【堆内存的对象内部中存储,所以访问该数据的时候必须先创建对象,通过引用方式访问】
	String name;//实例变量:必须采用 “ 引用. ” 的方式访问
	
	//构造方法
	public Customer(){
	}

	/*
	没有static关键字的变量被称为实例变量。
	没有static关键字的方法被称为实例方法。
	实例方法怎么访问? “ 引用. ” 
	*/
	//顾客购物的行为
	//每一个顾客购物的最终结果是不一样的。所以购物这个行为属于对象级别的行为
	//由于每一个对象在执行购物这个动作的时候,最终结果不同,所以购物这个动作必须有对象的参与
	//当一个行为或动作执行的过程当中是需要对象参与的,那么这个方法一定要定义为实例方法,不要带static关键字
	public void shopping(){
		//当张三在购物的时候,输出:张三在购物
		//当李四在购物的时候,输出:李四在购物
		//System.out.println("xxx在购物!");

		//由于name是一个实例变量,所以这个name访问的时候一定访问的是当前对象的name
		//所以多数情况下,“ this ” 是可以省略的
		System.out.println(name + "在购物!");

		//完整写法
		System.out.println(this.name + "在购物!");
	}
	//带有static
	public static void doSome(){
		
		//这个执行过程中没有当前对象,因为带有static的方法是通过类名的方式访问的
		//或者说这个 " 上下文 " 当中没有 " 当前对象 " ,自然也不存在this。
		//this代表的是当前正在执行这个动作的对象
		
		//以下程序为什么编译错误呢?
		//doSome方法调用不是对象去调用,是一个类名去调用,执行过程中没有 " 当前对象 "。
		//name是一个实例变量,以下代码的含义是:访问当前对象的name
		//没有 " 当前对象 ",自然也不能访问当前对象的name
		//System.out.println(name);

		// static的方法调用不需要对象,直接使用类名,所以执行过程中没有当前对象,所以不能使用this
		//System.out.println(this);
	}

	public static void doOther(){
		//假设想访问name这个实例变量的话应该怎么做?
		//System.out.println(name);//编译报错

		//可以采用以下方案,但是以下方案绝对不是访问的当前对象的name
		//创建对象
		Customer c = new Customer();
		System.out.println(c.name);//这里访问的name是c引用指向对象的name
			
	}
}
public class CustomerTest{
	public static void main(String[] args){
		
		//创建Customer对象
		Customer c1 = new Customer();
		c1.name = "zhangsan";

		//c1购物
		c1.shopping();

		//再创建Customer对象
		Customer c2 = new Customer;
		c2.name = "lisi";

		//c2购物
		c2.shopping();

		//调用doSome方法(修饰符列表上有static)
		//采用 “ 类名. ” 的方式访问。显然这个方法在执行的时候不需要对象的参加
		Customer.doSome();

		//调用doOther
		Customer.doOther();//null;
		
	}
}

java中的this关键字_第1张图片

测试一下

结论:在带有static的方法当中,不能 “ 直接 ” 访问实例变量和实例方法。因为实例变量和实例方法都需要对象的存在,而static的方法当中是没有this的。也就是说当前对象是不存在的,自然也是无法访问当前对象的实例变量和实例方法

public class ThisTest{
	
	//带有static
	//主方法
	public static void main(String[] args){
		
		//调用doSome方法
		ThisTest.doSome();

		//调用doSome方法
		doSome();

		//调用doOther方法
		//编译错误
		//ThisTest.doOther();//实例方法必须先创建对象,通过 “ 引用. ” 的方式访问

		//以下代码表示的含义:调用当前对象的doOther方法
		//但是由于main方法中没有this,所以以下方法不能调用
		//doOther();
		//this.doOther();

		ThisTest tt = new ThisTest();
		tt.doOther();		
	}

	//带有static
	public static void doSome(){
		System.out.println("do some!");
	}

	//实例方法
	public void doOther(){
		// This表示当前对象
		System.out.println("do other!");
	}

	// run是实例方法,调用run方法的一定是有对象存在的
	//一定是先创建了一个对象才能调用run方法
	public void run(){
		//在大括号中的代码执行过程当中,一定是存在当前对象的。也就是说这里一定是有this的
		System.out.println("run execute!");

		//doOther是一个实例方法。实例方法调用必须有对象的存在
		//以下代码表示的含义就是调用当前对象的doOther方法
		doOther();// This.大部分情况下都是可以省略的。
		//this.doOther();//比较完整的写法
	}
	
}

2. this什么情况下不省?

  • this 用来区分局部变量和实例变量的时候,“ this. ”不能省略
public class User{
	
	//属性
	private int id;//实例变量
	private String name;
	
	//构造函数
	//无参
	public User(){
	}
	
	//有参
	public User(int id, String name) {
			this.id = id;
			this.name = name;
	}
	
	//setter and getter
	
	//这种编写方式可以,但变量名最好见名知意
	/*
	public void setId(int a){
		id = a;
		//this.id = a;省略this
	}
	*/
	
	/*
	public void setId(int id){
		id = id;//java有就近原则,此处等号两侧的id都是setId方法的形式参数列表里的int id
				//以上程序的id和属性 “ private int id; ” 中的实例变量id无关
	}
	*/
	
	/*
	public void setId(int id){
		//等号前边的this.id是实例变量id
		//等号后边的id是局部变量id
		this.id = id;
	}	
	*/
	
	public int getId() {
			return id;
	}
	public void setId(int id) {
			this.id = id;
	}
	public String getName() {
			return name;
	}
	public void setName(String name) {
			this.name = name;
	}
}

测试一下

public class UserTest{
	public static void main(String[] args){
		User u1 = new User(100,"zhangsan");//可以同时调用无参数构造方法,或者添加参数,调用有参数构造方法
		System.out.println(u1.getId);
		System.out.println(u1.getName);

		//想修改名字
		u1.setName();
	}
}

3.this可以用在哪里?

  1. 可以使用在实例方法当中代表当前对象【语法格式:this】
  2. 可以使用在构造方法当中,通过当前的构造方法调用其他的构造方法【语法格式:this(实参) 】
  3. 【记忆!!】:this()这种语法只能出现在构造函数第一行
public class Date{
	
	//属性
	private int year;
	private int month;
	private int day;

	//构造函数
	//有参
	public Date(int year, int month, int day) {
		this.year = year;
		this.month = month;
		this.day = day;
	}
	
	/*
	需求:当程序员调用以下无参数的构造方法的时候,默认创建的日期是 “ 1970 - 1 - 1 ” 
	*/
	//无参
	public Date() {
		/*
		this.year = 1970;
		this.month = 1;
		this.day = 1;
		*/

		//以上代码可以通过调用另一个构造方法来完成
		//但前提是不能创建新的对象。以下代码表示创建了一个全新的对象
		//ps:构造方法调用:new 构造方法名(实参列表)
		//new Date(1970,1,1);

		//需要采用以下的语法来完成构造方法的调用
		//这种方式不会创建新的Java对象,但同时又可以达到调用其他的构造方法
		this(1970,1,1);
		//sun公司为我们提供一套语法,这套语法可以让我们通过一个构造方法去调用另外一个构造方法,但是不创建对象
	}
	
	//setter and getter
	public int getYear() {
		return year;
	}
	public void setYear(int year) {
		this.year = year;
	}
	public int getMonth() {
		return month;
	}
	public void setMonth(int month) {
		this.month = month;
	}
	public int getDay() {
		return day;
	}
	public void setDay(int day) {
		this.day = day;
	}

	//对外提供一个方法,可以将日期打印输出到控制台
	//实例方法
	public void print(){
		System.out.println(this,year + "年" + this.month + "月" + this.day + "日")
	}
}

测试一下

public class DateTest{
	public static void main(String[] args){
		
		//创建日期对象1
		Date time1 = new Date();
		time1.print();//1970年1月1日
		
		//创建日期对象2
		Date time2 = new Date(2008,8,8);
		time2.print();//2008年8月8日
	}
}

练习题 1 :

ps:没有省略的编写方式可以不写

public class Tesr{

	//没有static的变量
	int i = 10;

	//带有static的方法
	public static void doSome(){
		System.out.println("do some!");
	}

	//没有static的方法
	public void doOther(){
		System.out.println("do other!");
	}
		
	//带有static的方法
	public static void method1(){
		//调用doSome
		//完整方式的调用
		//省略方式的调用

		//调用doOther
		//完整方式的调用
		//省略方式的调用

		//访问i
		//完整方式访问
		//省略方式访问
	}
	
	//没有static的方法
	public void method2(){
		//调用doSome
		//完整方式的调用
		//省略方式的调用

		//调用doOther
		//完整方式的调用
		//省略方式的调用

		//访问i
		//完整方式访问
		//省略方式访问
	}

	//主方法
	public static void main(String[] args){
		//要求在这里编写程序调用method1
		//使用完整方式调用
		//使用省略方式调用

		//要求在这里编写程序调用method2
		//使用完整方式调用
		//使用省略方式调用
	}
}

题 1 答案:

public class Tesr{

	//没有static的变量
	int i = 10;

	//带有static的方法
	public static void doSome(){
		System.out.println("do some!");
	}

	//没有static的方法
	public void doOther(){
		System.out.println("do other!");
	}
	
	//带有static的方法
	public static void method1(){
		//调用doSome
		//完整方式的调用
		Test.doSome();
		//省略方式的调用
		doSome();

		//调用doOther
		//完整方式的调用
		Test t = new Test();
		t.doOther();
		//省略方式的调用
		//无

		//访问i
		//完整方式访问
		System.out.println(t.i);
		//省略方式访问
		//无
	}
	
	//没有static的方法
	//没有static的方法里面有this
	public void method2(){
		//调用doSome
		//完整方式的调用
		Test.doSome();
		//省略方式的调用
		doSome();
		//this.doSome();见本笔记附篇

		//调用doOther
		//完整方式的调用
		this.doOther();
		//省略方式的调用
		doOther();
		
		//访问i
		//完整方式访问
		System.out.println(this.i);
		//省略方式访问
		System.out.println(i);
	}

	//主方法
	public static void main(String[] args){
		//要求在这里编写程序调用method1
		//使用完整方式调用
		Test.method1();
		//使用省略方式调用
		method1();

		//要求在这里编写程序调用method2
		//使用完整方式调用
		Test t = new Test();
		t.method2();
		//使用省略方式调用
		//无
	}
}

附篇

什么情况下程序在运行的时候会出现空指针异常呢?

---->空引用访问实例相关的数据,因为实例相关的数据就是对象相关的数据,这些数据在访问的时候必须有对象的参与,当空引用的时候对象不存在,访问这些实例数据一定会出现空指针异常。

---->实例相关的数据包括

  • 实例变量【对象需要存在】
  • 实例方法【对象需要存在】
public class Test{
	public static void main(String[] args){
		Test.doSome();//do some!
		doSome();//do some!

		Test t = new Test();
		t.doSome();//do some!

		//引用是空
		t = null;

		//带有static的方法,其实既可以采用类名的方式访问,也可以采用引用的方式访问
		//但是即使采用引用的方式去访问,实际上执行的时候和引用指向的对象无关
		//在myeclipse中开发的时候,使用引用的方式访问带有static的方法,程序会出现警告
		//所以带有static的方法还是建议使用类名的方式访问
		t.doSome();//这里不会出现空指针异常
					//do some!
		
	}
	//带有static的方法,需要使用类名的方式访问
	public static void doSome(){
		System.out.println(do some!);
	}
}

你可能感兴趣的:(java基础,java,开发语言)