之前的文章都是关于Android的使用,这次想写一些关于Java的知识,总结一下Java的使用。这次写的是关于Java this的使用,介绍以下内容:

  1. this的概念
  2. this的各种应用
  3. 总结

this 是什么

在写一个方法的时候,如果想在方法内部获得对当前对象的引用就可以用this.this表示对“调用方法的那个对象”的引用。也就是说this指的是方法所属的类的对象的引用。根据这个定义,我们可以总结出很多关于this的用法。

  1. 当局部变量与成员变量重名的时候,可以用this表明用的是对象的成员变量。
  2. 当方法需要一个该类的对象做参数的时候,可用this代替。
  3. 在Android开发中,我们经常需要对事件处理写一个内部类或者匿名内部类,在内部类里用this,按照刚才的定义,指的就是内部类的对象,如果想要用外部类的对象,则要外部类名.this的形式表示外部类的对象的引用。
  4. 在构造函数中,可以用this来调用另一个构造函数。
  5. 当一个方法需要返回对当前对象的引用的时候,可以用return this。这时就可以在不断对这个对象进行多次这种方法的操作。

下面会针对每一种用法

进行说明和举例。

this的用法1

在Java程序中,如果一个方法中的参数与成员变量的名称是一样的时候,我们可以用this来指定调用的成员变量,例子如下:

/**
* Created by byhieg on 16-4-23.
*/
public class A { public String s = "A"; public A() { } public A(String s) {
System.out.println("s的值 = " + s);
s = "B";
System.out.println("经过s=\"B\"赋值后成员变量s的值");
System.out.println("成员变量s的值 = " + this.s);
this.s = "B";
System.out.println("经过this.s=\"B\"赋值后成员变量s的值");
System.out.println("成员变量s的值 = " + this.s);
} public void show() {
System.out.println("无参构造器中成员变量s的值 = " + s);
} public static void main(String[] args) {
new A().show();
System.out.println("调用含参构造器后");
new A("C");
}
}

运行结果如下:

无参构造器中成员变量s的值 = A
调用含参构造器后
s的值 = C
经过s="B"赋值后成员变量s的值
成员变量s的值 = A
经过this.s="B"赋值后成员变量s的值
成员变量s的值 = B

我们从这个程序可以看出来,当局部变量没有的时候,直接输出s不用加this,编译器也知道s指的是成员变量,当有局部变量的时候,编译器首先会用局部变量,这也就是在调用含参构造器后,直接输出s的值,s实际指的是局部变量,后续一切对s的操作,都是指的是局部变量s。这时,如果我们要对成员变量进行操作,就要用this.s表明是对对象的成员变量进行操作。

通过刚才的分析,我们已经可以看出this就是指的对当前对象的引用,所以既然是对象的引用,那么他不仅可以调用成员变量,还可以调用成员方法,一个方法中,可以通过this来调用其他方法。话虽如此,不过恐怕很多程序都是在方法中不加this直接调用,因为当前方法中this引用会自动应用于同一类中的其他方法。

this的用法2

在写一个方法的时候,如果该方法需要一个该类的对象做参数的时候,通常传入this代指该类的对象,具体的使用场景如下:

在Android开发中,我们的一些方法经常需要context作为一个参数传进去,通常我们传入的都是context的子类,即当前Activity的对象this进去。

我们可以看一下下面的代码:

/**
* Created by byhieg on 16-4-23.
*/
class B {
B(A a) {
a.show();
}
}
public class A { public void doB() {
new B(this);
}
public void show() {
System.out.println("我是A");
} public static void main(String[] args) {
new A().doB();
}
}

输出我是A

这个例子虽然写的很特意,但我们可以看出this在这里面取得的作用,this作为该类的对象的引用,在这里this就是指A的对象的引用。因为this是在A类的方法中传进去的所以指的是A的对象的引用。我们可以看一下下面的有趣例子:

/**
* Created by byhieg on 16-4-23.
*/
class B {
public B() {
System.out.println("这里的this是" + this.getClass().getSimpleName());
} public void Bshow() {
System.out.println("这里的this是" + this.getClass().getSimpleName());
}
}
public class A extends B {
public A() {
}
public static void main(String[] args) {
new A();
new B().Bshow();
}
}

结果很值得讨论,结果如下:

这里的this是A
这里的this是B
这里的this是B

明明是this出现B的构造器内,按照刚才说的不是应该指的是B吗?其实,注意刚才说的是this是指从那个方法中传进去那个类的对象。jvm在执行编译的时候,在成员方法中,会默认隐藏的传递一个参数,这个参数就是当前调用的对象本身。换句话说,虽然new A()的时候会先执行父类的默认构造函数,但此时已经把JVM已经秘密的传入的A的对象,所以我们可以看出输出的this是A。而在new B()的时候,传入的当然就是B的对象,所以输出的this就是B。

this的用法3

在Android开发中,我们经常需要对事件处理写一个内部类或者匿名内部类,在内部类里用this,按照刚才的定义,指的就是内部类的对象,如果想要用外部类的对象,则要外部类名.this的形式表示外部类的对象的引用。这个没什么细说的,直接看下面的例子算了

/**
* Created by byhieg on 16-4-23.
*/
public class A {
int i = 1; public A() {
Thread thread = new Thread() {
public void run() {
for (int j = 0;j < 2;j++) {
//调用外部类的方法
A.this.run();
}
}
};
thread.start();
} public void run() {
System.out.println("i = " + i);
i++;
} public static void main(String[] args) throws Exception {
new A();
}
}

这里run方法和内部类里面的run重复了,如果想要调用A的run方法就需要A的对象→this,但如果直接在内部类里面用this,则this就指的是内部类的对象,所以我们需要加上外部类的名字。A.this来明确表明这是A的对象。

this的用法4

在构造函数中,可以用this来调用另一个构造函数。这是this比较独特的用法,即在构造器中,如果为this添加了参数列表,那么这将产生对符合参数列表的某个构造器的明确调用。这样我们就可以在构造器中调用其他构造器,但书写上有所限制,必须将构造器的调用置于最初始处,而且只能用一次。

例子如下:

/**
* Created by byhieg on 16-4-23.
*/
public class A {
int a ,b;
public A(int a) {
this.a = a;
System.out.println(this.a);
}
public A(int a, int b) {
this(a);
this.b = b;
System.out.println(this.a + " " + this.b);
}
public static void main(String[] args) {
new A(2);
new A(2, 3);
}
}

具体的用法就如上面所示,我们可以打开调试器看一看里面的信息,如下图

我们可以看出this作为当前的对象,里面存放这该类的三个成员变量,我们可以很容易验证,无论this调用什么方法,内存中永远存放这个类的成员变量,所以才可以通过this对成员变量进行修改。

this的用法5

当一个方法需要返回对当前对象的引用的时候,可以用return this。这时就可以在不断对这个对象进行多次这种方法的操作。

这是一个很神奇的操作,因为这个方法的返回值是当前对象的引用,因此你可以用这个引用继续调用其他方法,很容易一行语句执行多次操作,就像python的一行语法一样。

我们看一个好玩的例子

/**
* Created by byhieg on 16-4-23.
*/
public class A {
int i = 0;
public A add() {
i ++;
return this;
}
public A show() {
System.out.println(i);
return this;
}
public void end() {
System.out.println("到此为止");
} public static void main(String[] args) {
new A().add().show().add().show().add().show().add().show().add().show().end();
}
}

输出结果显而易见,我就不放出来了。

总结

我们这里讨论了this的五种用法,但是都是根据this的定义引申出在不同情况下的用法。this只能在方法内部使用,当调用方法中含有this的时候,this就指的调用该方法的对象的引用,当方法参数中需要传入一个类的对象的时候,用this代指这个传入类的对象。当用构造方法初始化成员变量的时候,JVM会默认传入当前对象来初始化成员变量。

Java this的一两点使用的更多相关文章

  1. Java static 的一两点使用

    这篇文章是关于Java static关键字的使用,主要会介绍以下的内容: static 的概念 static的各种应用 总结 static 是什么 static 顾名思义是静态的意思.与this相对, ...

  2. Spark案例分析

    一.需求:计算网页访问量前三名 import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ...

  3. 这些天自身努力的体会,关于java方面的

    以前也是接触过java,这学期的软件工程课和周围同学各种比赛取得不错的成绩,确实令人倍感压力.为此这几天使劲脑补了一下java的知识,甚至不惜为此翘课,了解了java中的网络编程,对于sokectse ...

  4. Java工程师如何在1个月内做好面试准备?

    作者:石杉的架构笔记 写在前面 春节长假转眼已过,即将迎来的是一年一度的金三银四跳槽季. 假如你准备在金三银四跳槽的话,那么作为一个Java工程师,应该如何利用1个月的时间,快速的为即将到来的面试进行 ...

  5. 【金三银四跳槽季】Java工程师如何在1个月内做好面试准备?

    目录 一.写在前面 二.技术广度的快速准备 三.技术深度的快速准备 四.基础功底的快速准备 五.下篇预告 一.写在前面 春节长假转眼已过,即将迎来的是一年一度的金三银四跳槽季. 假如你准备在金三银四跳 ...

  6. JAVA特性面试题:

    1.简要介绍java程序的健壮性. 答:JAVA程序会在编译和运行的时候自动的检测可能出现的错误,而且它是一种强类型语言,对于类型的检查很严格,而且它的垃圾回收机制也有效的避免了内存的泄漏. 2.为什 ...

  7. Java面向对象之异常【一】

    目录 Java面向对象之异常[一] 异常的继承体系 Error Exception 异常是否受检 unchecked exceptions(不受检异常) checked exceptions(受检异常 ...

  8. 【JAVA进阶架构师指南】之五:JVM性能调优

    前言   首先给大家说声对不起,最近属实太忙了,白天上班,晚上加班,回家还要收拾家里,基本每天做完所有事儿都是凌晨一两点了,没有精力再搞其他的了.   好了,进入正题,让我们来聊聊JVM篇最后一个章节 ...

  9. 故障重现(内存篇2),JAVA内存不足导致频繁回收和swap引起的性能问题

    背景起因: 记起以前的另一次也是关于内存的调优分享下   有个系统平时运行非常稳定运行(没经历过大并发考验),然而在一次活动后,人数并发一上来后,系统开始卡. 我按经验开始调优,在每个关键步骤的加入如 ...

随机推荐

  1. 【转】Asp.net关闭弹出窗口刷新父窗口

    通常情况下,关闭窗口时不需要对父窗口做任何操作,但如果子窗口是某一对象的修改画面,这时,当关闭子窗体时就需要对父窗口刷新,刷新可以通过三种方式来实现:1,采用window.opener.locatio ...

  2. iOS路径沙盒文件管理(转载)

    iOS路径沙盒文件管理,看到博主总结的很好,转载过来,原文:http://www.aichengxu.com/view/35264 一.iOS中的沙盒机制 iOS应用程序只能对自己创建的文件系统读取文 ...

  3. 将Unreal4打包后的工程嵌入到Qt或者桌面中

    #include "widget.h" #include "ui_widget.h" #include "windows.h" #inclu ...

  4. [转]ORACLE中Like与Instr模糊查询性能大比拼

    instr(title,'手册')>0  相当于  title like '%手册%' instr(title,'手册')=1  相当于  title like '手册%' instr(titl ...

  5. 实验二 c语言文法

    <程序>-><声明>|<程序><函数> <函数>-><修饰符><标识符><形式参数>< ...

  6. Visual Studio 2015 Update 2正式版下载地址

     转载自:王彬的博客 地址:http://blog.sina.com.cn/s/blog_55f899fb0102wcwg.html Visual Studio Professional 2015(带 ...

  7. Github初学者教程(一)

    如果你是一名程序员,或者是相关专业的学生,那么Github你不应不知道.很多开源组织和大神,会选择在Github这个平台上,发布他们的开源项目,学会使用Github将能够给你的学习和工作带来巨大帮助! ...

  8. 【BZOJ】4056: [Ctsc2015]shallot

    题意 在线.可持久化地维护一条二维平面上的折线,支持查询与任意一条直线的交点个数. 点的个数和操作个数小于\(10^5\) 分析 一条折线可以用一个序列表示,可持久化序列考虑用可持久化treap. 如 ...

  9. MongoDB常用操作命令大全

    成功启动MongoDB后,再打开一个命令行窗口输入mongo,就可以进行数据库的一些操作.输入help可以看到基本操作命令,只是MongoDB没有创建数据库的命令,但有类似的命令 如:如果你想创建一个 ...

  10. php安装配置那些事(本文纯属个人记事与技术无关)

    上周由于项目需要,又拿起了三年没动过的php,从安装环境到配置,大体已经忘干净,于是咨询同学问度娘,终于在我的win7系统下安装了xampp的集成环境+NetBeans IDE 8.0,于是导入项目文 ...