之前的文章都是关于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. HDU 4467 分块

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4467 题意:给定n个点m条边的无向图,点被染色(黑0/白1),边带边权.然后q个询问.询问分为两种: ...

  2. SQL 数字分割的字符串

    :表示包含正数或者负数.或者0 即表示,数字的字段! select * from 表名 where isnull(字段名,'')<>'' 同时排除空值和null的情况 select coo ...

  3. JQuery.validate.js 表单验证

    官方网站:http://bassistance.de/jquery-plugins/jquery-plugin-validation/API: http://jquery.bassistance.de ...

  4. PHP unset()函数销毁变量 但没有实现释放内存

    <?PHP $a = "hello";$b = &$a;unset( $b );echo $a; // 输出 helloecho $b; // 报错$b = &quo ...

  5. Python 基础语法学习笔记

    以下运行结果均通过Python3.5版本实测! 1.列表转换为字典 a = ['a', 'b'] b = [1, 2] c = ['c','d'] print (dict([a,b,c])) 输出结果 ...

  6. Linux Shell 数组

    shell 数组一般都是一维数组. 1. 数组的声明 declare -a arr 该命令将声明一个数组arr,实际上不声明也可以直接定义数组. 2. 数组的初始化 arr=(1 2 3):该命令定义 ...

  7. btrace使用

    btrace使用 目录btracee是btrace的解压目录 btrace/btrace是btrace的项目工程 root@ubuntu:/usr/local/bogon/btrace# tree b ...

  8. 搭建ssm的领悟

    今天搭建了ssm,但是一直报错误 "Cannot load JDBC driver class 'com.mysql.jdbc.Driver" 我以为是版本的问题就换,以为是路径加 ...

  9. Git Commands Quick Notes

    Fetch This command is to make sure your local repository has the same knowledge of the remote-tracki ...

  10. [SE0]简单的搜索引擎原理

    1.简单了解搜索引擎收录的原理  包括baidu. google .yahoo 在内的各大搜索引擎在内基本上搜录网站的原理大致相同(除了国内某些网站 网1新 l 等采取人工登记的办法),搜索引擎都是采 ...