Java关键字this(动力节点Java学院整理)

我们通常在用Java中的this关键字的时候,都知道this是代表正在调用这个类的方法的当前实例。通常情况下理解this关键字还是很容易的,但是在我初学的时候,有一个疑问却一直不能很清晰的理解,现在慢慢的理解了,就想把它记下来,也许有人和我有相同的疑问,说不定可以帮助到别人。我们还是先简单的看看通常情况下this的作用吧。比如下面的代码:

public class Leaf {
 private int i = 0;
 Leaf increment() {
  i++;
  return this;
 }
 void print() {
  System.out.println("i = " + i);
 }
 public static void main(String[] args) {
  Leaf x = new Leaf();
  x.increment().increment().print();
 }
}

在Leaf类的main方法中,我们new了一个Leaf实例 x,然后x实例调用increment()方法。如果increment()是普通的方法或者void方法,这个地方就没有什么值得我们研究的了。特殊的是,在increment()方法中,我们return的是一个this,这个this代表的就是我们刚刚创建的x。因为x正在调用increment()方法,所以,increment()方法this就很明显代表的是Leaf的x实例了。

这看起来没有什么可讨论的,this就是代表的调用该方法的实例x。可是,假如我们把main()函数修改成下面的样子

public static void main(String[] args) {
 Leaf x = new Leaf();
 x.increment().increment().print();

 Leaf y = new Leaf();
 y.increment().increment().print();
}

以上修改的代码中,我们增加创建了一个Leaf实例y,然后y也连续调用调用了两次increment()。现在问题来了,假如 x,y同时调用的increment()方法,那么this到底能代表谁呢?你可能会觉得这有什么问题,x调用increment()方法,this就代表x, y调用increment()方法,this就代表y。可问题是,当我们讲调用方法的时候,在jvm层面上是找到Leaf类中increment()方法所在的内存地址,然后在java虚拟机栈中创建栈帧.

然后在栈帧中执行方法里面的代码。现在看到了吧,也就是说,在jvm执行方法层面,没有所谓的x调用,y调用了,那么,方法中的this到底是怎么确定指向哪个实例的呢?

我们还是来看看Leaf类字节码中是怎么展示的,是不是我们漏了什么,如果我们没有把x实例或者y实例传递到方法里面去,那么,在jvm执行方法的时候,是不可能知道this具体指向哪个实例的。

到这里,我们看到在increment()方法中,编码中没有参数,但是在字节码里面却显示参数个数为1,仔细想想,结果已经很明显了:jvm在执行编译的时候,在实例方法中,会默认隐藏的传递一个参数,这个参数就是当前调用的实例本身。比如x调用,隐藏就把x传过去,y调用,就把y传过去。所以,我们的this才能在jvm执行方法层面确定到底指向的是谁。

上面的结论是我们自己推断出来的,有没有那本书对这个有详细的描述呢?《java编程思想》里面,对这块是这样描述的:

假定我们在一个方法的内部,并希望获得当前对象的句柄。由于那个句柄是由编译器“秘密”传递的,所以没有标识符可用。然而,针对这一目的有个专用的关键字:this。

在里面讲的这个编译器秘密传递的句柄,就是我们这里的这个隐藏参数。

到此为止,关于this的描述想必已经很清楚了,我们在jvm层面对它进行了理解。那么,各位有没有兴趣在看下下面的这个例子,想想这个基类B中的this代表了什么呢?

public class B {
 public B() {
  System.out.println(this.getClass().getSimpleName());
  System.out.println(((A) this).a);
 }
}
public class A extends B {
 public int a = 100;
 public A() {
  a = 200;
 }
 public static void main(String[] args) {
  new A();
 }
}

这个例子原本是为了了解java具有继承结构的时候类是怎么完成初始化的,可是这里面的B类中的构造函数比较特殊:B类中的构造函数中的this输出的SimpleName是A。通常我们遇到的情况,B类中的this输出的SimpleName应该是B,可是这里却是A?为什么?

在上面我们讲this的过程中,其实已经涉及到这块了,在调用java方法创建栈帧的时候,jvm会秘密的传递一个当前实例。所以,当我们在执行A的构造函数的时候,默认会调用父类B的构造函数,在调用父类B构造函数的时候,秘密的传进去的当前实例是 A的实例----因为是在A的构造函数中调用的B,所以,这个地方的this反而代表了A。

以上所述是小编给大家介绍的Java关键字this(动力节点Java学院整理),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

时间: 2017-03-29

Java this 关键字的使用方法详解

Java this 关键字的使用方法详解 构造方法中的this关键字 构造方法是一个类的对象在通过new关键字创建时自动调用的,在程序中不能向调用其他方法一样通过方法名(也就是类名)来调用.但如果一个类有多个构造方法,可以在一个构造方法中通过this(paras-)来调用其他的构造方法. 使用this来调用其他构造方法有如下几个约束. 1) 只能在构造方法中通过this来调用其他构造方法,普通方法中不能使用. 2) 不能通过this递归调用构造方法,即不能在一个构造方法中通过this直接或间接调

Java this、final等关键字总结

this 关键字this引用对象自身.它也可以在构造方法内部用于调用同一个类的其他构造方法. 隐藏的静态变量可以通过"类.静态变量"来引用,而隐藏的实例变量就需要使用"this.实例变量"来引用. 调用一个重载的构造方法this引用是必须的. this是个隐式参数,代表当前对象 publie class Student{ private String name; public void setName(String name){ this.name=name; //

彻底理解Java中this 关键字

this关键字再java里面是一个我认为非常不好理解的概念,:)也许是太笨的原因 this 关键字的含义:可为以调用了其方法的那个对象生成相应的句柄. 怎么理解这段话呢? thinking in java里面有这么一个例子 有两个同一个类型的对象,分别叫做a和b,那我们怎样区别在调用方法f()的时候,是谁再调用这个方法呢? 例如: class Banana { void f(int i){ /***方法主体*****/ } } Banana a = new Banana();//生成Banana

Java 中This用法的实例详解

 Java 中This用法的实例详解 用类名定义一个变量的时候,定义的只是一个引用,外面可以通过这个引用来访问这个类里面的属性和方法. 那们类里面是够也应该有一个引用来访问自己的属性和方法纳? 呵呵,Java提供了一个很好的东西,就是 this 对象,它可以在类里面来引用这个类的属性和方法.先来个简单的例子: public class ThisDemo { String name="Mick"; public void print(String name){ System.out.pr

详解Java使用super和this来重载构造方法

详解Java使用super和this来重载构造方法 实例代码: //父类 class anotherPerson{ String name = ""; String age = ""; public String getAge() { return age; } public void setAge(String age) { this.age = age; } public void setName(String name){ this.name = name;

java this 用法详解及简单实例

java this 用法详解 用类名定义一个变量的时候,定义的只是一个引用,外面可以通过这个引用来访问这个类里面的属性和方法. 那们类里面是够也应该有一个引用来访问自己的属性和方法纳? 呵呵,JAVA提供了一个很好的东西,就是 this 对象,它可以在类里面来引用这个类的属性和方法.先来个简单的例子: public class ThisDemo { String name="Mick"; public void print(String name){ System.out.printl

深入理解java中this关键字的使用

一,表示类中属性 1,没有使用this的情况 class Person{ // 定义Person类 private String name ; // 姓名 private int age ; // 年龄 public Person(String name,int age){ // 通过构造方法赋值 name = name ; age = age ; } public String getInfo(){ // 取得信息的方法 return "姓名:" + name + ",年龄

Java super和this的对比及使用

Java super和this的对比及使用 super和this的异同 1)super(参数列表):调用父类中的某一个构造函数(应该为构造函数中的第一条语句) this(参数列表):调用本类中另一种形成的构造函数(应该为构造函数中的第一条语句) 2)super: 它引用当前对象的直接父类中的成员(用来访问直接父类中被隐藏的父类中成员数据或函数,基类与派生类中有相同成员定义时如:super.变量名   super.成员函数据名(实参) this:它代表当前对象名(在程序中易产生二义性之处,应使用t

Java this()和super()的使用注意

Java this()和super()的使用注意 使用super和this应该注意这些: 1)调用super()必须写在子类构造方法的第一行,否则编译不通过.每个子类构造方法的第一条语句,都是隐含地调用super(),如果父类没有这种形式的构造函数,那么在编译的时候就会报错. 2)super()和this()类似,区别是,super从子类中调用父类的构造方法,this()在同一类内调用其它方法. 3)super()和this()均需放在构造方法内第一行. 4)尽管可以用this调用一个构造器,但

java中this与super关键字的使用方法

java中this与super关键字的使用方法 这几天看到类在继承时会用到this和super,这里就做了一点总结,与各位共同交流,有错误请各位指正~ this this是自身的一个对象,代表对象本身,可以理解为:指向对象本身的一个指针. this的用法在java中大体可以分为3种: 1.普通的直接引用 这种就不用讲了,this相当于是指向当前对象本身. 2.形参与成员名字重名,用this来区分: class Person { private int age = 10; public Perso

浅谈java面向对象(类,封装,this,构造方法)

无论面向对象还是面向过程, 这俩都是解决问题的思路而已, 只是角度不同. 面向过程: 强调解决问题的每一个步骤都亲力亲为,每一个细节都自己手动实现. 面向对象: 使用特定功能对象去解决特定的问题, 每一个细节不需要关注,只需要创建对应的对象即可. 面向对象是基于面向过程的 类和对象及他们的关系 类: 具有相同特征和行为(功能)的事物的统称 , 是一个抽象概念 对象: 这类事物中某个确定的个体 类和对象的关系 一个类可以创建多个对象 , 类是对象的抽象, 对象是类的实例. 描述一个事物---->

浅谈java面向对象中四种权限

俗话说没有规矩就没有方圆,java作为一门严谨的面向对象的高级编程语言,自然对权限整个重要的问题有严格的控制. Java中,可以通过一些Java关键字,来设置访问控制权限: 主要有 private(私有), package(包访问权限),protected(子类访问权限),public(公共访问权限) 在java里,这些语句都可以修饰类中的成员变量和方法,但是只有public和友好型可以修饰类.举个例子: 接下来就详细解释一下这几种权限的差别(博客最后有表格)按权限由低到高:(高权限有低权限所有

浅谈java面向对象的数组化信息处理

虽然非常简单的东西,但对于一些自学的新手和前期理解的不够深的萌新来说,应该会有很大的帮助,有助于理解. 初学面向对象的时候,我想许多同学对此很纳闷.简单的问题复杂化,多此一举诸之云云. 那么往下看: package cn.bdqn.test3; import java.util.Scanner; public class Test1 { public static void main(String[] args) { //创建两个管理员对象 Admin a1 = new Admin(); a1.

浅谈java Properties类的使用基础

Properties类继承自HashTable,通常和io流结合使用.它最突出的特点是将key/value作为配置属性写入到配置文件中以实现配置持久化,或从配置文件中读取这些属性.它的这些配置文件的规范后缀名为".properties".表示了一个持久的属性集. 需要注意几点: 无论是key还是value,都必须是String数据类型. 虽然继承自HashTable,但它却没有使用泛型. 虽然可以使用HashTable的put方法,但不建议使用它,而是应该使用setProperty()

浅谈Java实现面向对象编程java oop

一.对象的综述 面向对象编程(OOP)具有多方面的吸引力.对管理人员,它实现了更快和更廉价的开发与维护过程.对分析与设计人员,建模处理变得更加简单,能生成清晰.易于维护的设计方案.对程序员,对象模型显得如此高雅和浅显.此外,面向对象工具以及库的巨大威力使编程成为一项更使人愉悦的任务.每个人都可从中获益,至少表面如此. 所有编程语言的最终目的都是解决企业又或者人在现实生活中所遇到的问题,最初我们的程序可能长这样"11111100001",相信大家都不会陌生,只是大家没这么子去敲过代码.再

浅谈java的接口和C++虚类的相同和不同之处

C++虚类相当于java中的抽象类,与接口的不同之处是: 1.一个子类只能继承一个抽象类(虚类),但能实现多个接口 2.一个抽象类可以有构造方法,接口没有构造方法 3.一个抽象类中的方法不一定是抽象方法,即其中的方法可以有实现(有方法体),接口中的方法都是抽象方法,不能有方法体,只有声明 4.一个抽象类可以是public.private.protected.default,接口只有public 5.一个抽象类中的方法可以是public.private.protected.default,接口中的

浅谈java中BigDecimal类的简单用法

一.BigDecimal概述 ​ Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算.双精度浮点型变量double可以处理16位有效数,但在实际应用中,可能需要对更大或者更小的数进行运算和处理.一般情况下,对于那些不需要准确计算精度的数字,我们可以直接使用Float和Double处理,但是Double.valueOf(String) 和Float.valueOf(String)会丢失精度.所以开发中,如果我们需要精确计算的结果,则必须使用

浅谈java中math类中三种取整函数的区别

math类中三大取整函数 1.ceil 2.floor 3.round 其实三种取整函数挺简单的.只要记住三个函数名翻译过来的汉语便能轻松理解三大函数,下面一一介绍 1.ceil,意思是天花板,java中叫做向上取整,大于等于该数字的最接近的整数 例: math.ceil(13.2)=14 math.ceil(-13.2)=-13 2.floor,意思是地板,java中叫做向下取整,小于等于该数字的最接近的整数 例: math.floor(13.2)=13 math.floor(-13.2)=-

浅谈Java代码的 微信长链转短链接口使用 post 请求封装Json(实例)

废话不多说,直接上代码 String longUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + MpUtil.APPID + "&redirect_uri=" + MpUtil.HOMEPAGE + "/nweixinLoginPc.fo%3Frandomcode=" + randomcode + "&response_type=co

浅谈java中为什么实体类需要实现序列化

当客户端访问某个能开启会话功能的资源,web服务器就会创建一个HTTPSession对象,每个HTTPSession对象都会占用一定的内存,如果在同一个时间段内访问的用户太多,就会消耗大量的服务器内存,为了解决这个问题我们使用一种技术:session的持久化. 什么是session的持久化? web服务器会把暂时不活动的并且没有失效的HTTPSession对象转移到文件系统或数据库中储存,服务器要用时在把他们转载到内存. 把Session对象转移到文件系统或数据库中储存就需要用到序列化: jav