Java this关键字
介绍
this关键字用于引用当前实例,在Java语言中,当创建一个对象后,Java虚拟机就会为其分配一个指向对象本身的指针,这个指针就是“this”。
Java关键字this只能用于方法方法体内。当一个对象创建后,Java虚拟机(JVM)就会给这个对象分配一个引用自身的指针,这个指针的名字就是 this。因此,this只能在类中的非静态方法中使用,静态方法和静态的代码块中绝对不能出现this,并且this只和特定的对象关联,而不和类关联,同一个类的不同对象有不同的this。
应用
this关键字主要有三个应用: (1)this调用本类中的属性,也就是类中的成员变量; (2)this调用本类中的其他方法; (3)this调用本类中的其他构造方法,调用时要放在构造方法的首行。
引用成员变量
例1:观察以下的程序代码,看看会出现哪些问题呢?
class Student { private String name; //定义一个成员变量name public void setName(String name) {//设置姓名,定义一个形参name name=name; //将局部变量的值传递给成员变量 } public String getName( ) {//获得姓名 return "姓名:"+name; }} public class ThisExample01 { public static void main(String args[]) { Student stu=new Student(); stu.setName("李明"); System.out.println(stu.getName()); }}
运行结果:姓名:null
由运行结果可以看出,通过name=name并没有正确的将内容赋给属性,为什么呢?因为此时操作的name实际上是方法中的,跟类中的属性完全不沾边。
另外,这个程序代码中,有一个成员变量name,同时在方法中有个形式参数,参数名也是name。然后在方法中将形式参数name的值传递给成员变量name。虽然我们可以看明白这个代码的含义,但是作为Java编译器它是怎么判断使用哪个变量的呢?到底是将形式参数name的值传递给成员变量name,还是反过来讲成员变量name的值传递给形式参数name呢?
此时this这个关键字就起到作用了,这种情况下使用this这个关键字代表的就是类中的成员变量,又叫做类的属性。所以此时,为了明确的表示出哪一个是类中的属性,就要加上“this.属性名称”的操作,
将student类的代码改进如下:
class Student { private String name; public void setName(String name) { http://www.wenkuxiazai.com=name; //将形 参的值传递给成员变量 } public String getName( ) { return "姓名:"+name; }}
这时,代表的就是类中的成员变量,而赋值号右边的name则是方法的形式参数,代码name就是将形式参数的值传递给成员变量。
例1只是以一个形式参数为例。其实如果是局部变量的话,也是相同的道理。在方法体内定义的变量称为局部变量,在类的内部方法体的外部定义的变量称为成员变量。如果成员变量和方法中的局部变量的名字相同时,那么在方法中成员变量将会被屏蔽。如果这个时候还要使用成员变量,就需要使用关键字this。使用this引用成员变量的方法格式:this.成员变量名。
既然this能够调用本类中的成员变量,那么,this也可以调用本类中的成员方法。以例2为例,程序代码如下:
class Student { private String name; public void setName(String name) { this.print();//调用本类中的print方法 } public String getName( ) { return "姓名:"+name; } public void print( ) { System.out.println("设置相关信息如下……"); }} public class ThisExample02 { public static void main(String args[]) { Student stu=new Student(); stu.setName("李明"); System.out.println(stu.getName()); }}
运行结果:
设置相关信息如下…… 李明
一般情况下,在Java语言中引用成员变量或者成员方法都是以对象名.成员变量或者对象名.成员方法的形式。不过有些程序员即使在没有相同变量的时候,也喜欢使用this.成员变量的形式来引用变量 。这主要是从便于代码的阅读考虑。一看到这个this关键字就知道现在引用的变量是成员变量或者成员方法,而不是局部变量。这无形中就提高了代码的阅读性。
调用类的构造方法
在一个Java类中,构造方法是一个与类同名的方法,必须与类的名字相同。而且在Java类中必须存在一个构造方法。如果在代码中没有显示的体现构造方法的话,那么编译器在编译的时候会自动添加一个没有形式参数的构造方法。在一个类中可以存在多个构造方法,这些构造方法都采用相同的名字,只是形式参数不同。Java语言就凭用户的参数来判断调用哪一个构造方法。当一个类中有多个构造方法时,可以利用this关键字相互调用。假设,现在有一个类中存在多个构造方法,但是不管有多少个构造方法,只要对象一被实例化,就必须打印一句“新对象实例化”的信息出来,这时可以按照最原始的方式完成,具体代码如下:
class Student { private String name ; private int age ; public Student () { this("李明",20) ;//调用有两个参数的构造方法 System.out.println("新对象实例化") ; } public Student (String name) { this() ; } public Student (String name,int age) { this(name) ; this.age = age ; } public String getInfo(){ return "姓名:" + name + ",年龄:" + age ; }} public class ThisExample05 { public static void main(String args[]) { Student stu1 = new Student ("李小明",19) ; System.out.println(stu1.getInfo()) ; }} 这时候构造方法就出现了递归调用,程序出错。
Java编译器会根据所传递的参数数量的不同,来判断该调用哪个构造方法。所以,我们在实际编程的时候有时候需要在一个构造方法中对另一个构造方法进行调用。但是,在使用this关键字调用其他构造方法的时候,this()调用构造方法只能放在构造方法的首行,为的是能够为类中的属性初始化;而且至少有一个构造方法是不用this调用,否则程序会出现错误。
注意的是,使用this调用构造方法只适用于构造方法的调用,类中的其他方法不能使用这种方法。
返回对象的值
this最重要的特定就是表示当前对象,那什么叫当前对象呢?在Java中当前对象就是指当前正在调用类中方法的对象。使用this引用当前对象是指如果在类的方法中需要返回一个对象,并且该对象是方法所在的类的当前对象,可以使用this关键字作为方法的返回值。例如:
class Student { public String getInfo()//取得信息的方法 { System.out.println("Student类 --> " + this) ; // 直接打印this return null ; //为了保证语法正确,返回null }} public class ThisExample06{ public static void main(String args[]) { Student stu1 = new Student();//调用构造实例化对象 Student stu2 = new Student();//调用构造实例化对象 System.out.println("MAIN方法 --> " +stu1) ; //直接打印对象 stu1.getInfo() ; // 当前调用getInfo()方法的对象是stu1 System.out.println("MAIN方法 --> " +stu2) ; //直接打印对象 { private String name //姓名 private int age ; //年龄 public Student (){// 无参构造System.out.println("新对象实例化") ; } public Student (String name) { System.out.println("新对象实例化") ; } public Student (String name,int age) // 通过构造方法赋值 { System.out.println("新对象实例化") ; //为类中的name属性赋值 this.age = age ; //为类中的age属性赋值 } public String getInfo(){//取得信息的方法return "姓名:" + name + ",年龄:" + age ; }} public class ThisExample03 { public static void main(String args[]) { Student stu1 = new Student ("李明",20) ; //调用构造实例化对象 System.out.println(stu1.getInfo()) ; //取得信息 }}
这个例子中,一个无参的构造方法,一个提供一个参数用于设置姓名的构造方法,还有一个提供两个参数用于设置姓名和年龄的构造方法,这三个方法都是用来打印新对象实例化的信息,很明显,此时如果在各个构造方法中编写输出语句肯定是不合适的,其中有一些代码重复了,现在只是一行,所以感觉不出来,如果现在的代码有很多行的话,以上代码的缺陷就立刻显现出来了。那么,最好让构造方法间进行相互的调用,这时就可以用“this(参数列表)”的形式完成,用this修改以上的代码如下:
class Student { private String name ; private int age ; public Student(){ System.out.println("新对象实例化") ; } public Student (String name) { this() ; //调用本类中的无参构造方法 http://www.wenkuxiazai.com = name ; } public Student (String name,int age) { this(name); //调用有一个参数的构造方法 this.age = age ; } public String getInfo(){ //取得信息的方 法 return "姓名:" + name + ",年龄:" + age ; }} public class ThisExample04 { public static void main(String args[]) { Student stu1 = new Student ("李明",20) ; System.out.println(stu1.getInfo()) ; } }
一个类中有多个构造方法,因为其名字都相同,跟类名一致,那么这个this到底是调用哪个构造方法呢?
stu2.getInfo() ; // 当前调用getInfo()方法
}}
我们再用一个例子来解释this引用当前对象。public class Car
{ public Car getCarObject(){ return this; //返回当前对象}
public static void main(String[] args) { Car sc = new Car ();//创建一个Car对象 System.out.println( sc.getCarObject() instanceof Car);
}}
这里定义了一个返回类型为Car类型的方法getCarObject(),并使用this关键字返回当前的对象Car。在main()方法中创建一个Car对象并使用instanceof方法判断getCarObject()方法返回的对象与Car对象是否匹配。运行结果为true。
例子
package test;
public class ThisTest {
private int i=0;
//第一个构造器:有一个int型形参
ThisTest(int i){
this.i=i+1;//此时this表示引用成员变量i,而非函数参数i
System.out.println("Int constructor i——this.i: "+i+"——"+this.i);
System.out.println("i-1:"+(i-1)+"this.i+1:"+(this.i+1));
//从两个输出结果充分证明了i和this.i是不一样的!
}
// 第二个构造器:有一个String型形参
ThisTest(String s){
System.out.println("String constructor: "+s);
}
// 第三个构造器:有一个int型形参和一个String型形参
ThisTest(int i,String s){
this(s);//this调用第二个构造器
//this(i);
this.i=i++;//this以引用该类的成员变量
System.out.println("Int constructor: "+i+"/n"+"String constructor: "+s);
}
public ThisTest increment(){
this.i++;
return this;//返回的是当前的对象,该对象属于(ThisTest)
}
public static void main(String[] args){
ThisTest tt0=new ThisTest(10);
ThisTest tt1=new ThisTest("ok");
ThisTest tt2=new ThisTest(20,"ok again!");
System.out.println(tt0.increment().increment().increment().i);
//tt0.increment()返回一个在tt0基础上i++的ThisTest对象,
//接着又返回在上面返回的对象基础上i++的ThisTest对象!
}
}
运行结果:
Int constructor i——this.i: 10——11
String constructor: ok
String constructor: ok again!
Int constructor: 21
String constructor: ok again!
14
细节问题注释已经写的比较清楚了,这里不在赘述,只是总结一下,其实this主要要三种用法:
1、表示对当前对象的引用!
2、表示用类的成员变量,而非函数参数,注意在函数参数和成员变量同名是进行区分!其实这是第一种用法的特例,比较常用,所以那出来强调一下。
3、用于在构造方法中引用满足指定参数类型的构造器(其实也就是构造方法)。但是这里必须非常注意:只能引用一个构造方法且必须位于开始!
还有就是注意:this不能用在static方法中!所以甚至有人给static方法的定义就是:没有this的方法!虽然夸张,但是却充分说明this不能在static方法中使用!
说明在什么情况下需要用到this:
第一、通过this调用另一个构造方法,用发是this(参数列表),这个仅仅在类的构造方法中,别的地方不能这么用。
第二、函数参数或者函数中的局部变量和成员变量同名的情况下,成员变量被屏蔽,此时要访问成员变量则需要用“this.成员变量名”的方式来引用成员变量。当然,在没有同名的情况下,可以直接用成员变量的名字,而不用this,用了也不为错,呵呵。
第三、在函数中,需要引用该函所属类的当前对象时候,直接用this。
版权声明:本文为JAVASCHOOL原创文章,未经本站允许不得转载。