android
开发讨论群
2308505
群主是流氓
欢迎加入android200人开发讨论群,群号:2308505。
1、this 关键字
在整个Java 中,this关键字是一个最难为理解的关键字,this有三种用处:表示属性、表示方法、当前对象。
1.1 表示属性
可以通过构造方法或者是setter方法为类中的属性赋值,但是,如果说现在代码写成如下形式:
public class TestDemo1 { /** * @param args */ public static void main(String[] args) { Person pre = new Person("张三", 23); System.out.println(pre.getInfo()); } } class Person { private String name; private int age; public Person(String n, int a) { // 构造方法的参数名称并不明确 name = n; age = a; } public String getInfo() { return "姓名:" + name + " 年龄:" + age; } }
输出结果:姓名:张三 年龄:23 // 没有问题 |
我们单看n、a这两个参数并不知道表示的是什么意思,如果把n写成name,a写成age,就明白是要为类中的name、age属性进行传值的,但是,如果说现在代码写成如下形式:
public class TestDemo1 { /** * @param args */ public static void main(String[] args) { Person pre = new Person("张三", 23); System.out.println(pre.getInfo()); } } class Person { private String name; private int age; public Person(String name, int age) { // n = name, a = age,与类中的属性同名 name = name; age = age; } public String getInfo() { return "姓名:" + name + " 年龄:" + age; } }
输出结果:姓名:null 年龄:0 // 现在这个结果肯定不是我们想要的 |
这个时候构造方法上的确是可以清楚的知道要传递的是name和age的信息,但是最后的结果并没有真正的将传入的name和age两个属性赋予类中的name和age属性,在程序的开发之中,是以“{ }”为界,存在一种称为就近取用的原则,因为这个原则,所以之前构造方法中出现的name和age两个参数都是构造方法的参数,与类中的属性没有关系,所以,如果现在要想明确的表示操作的是类中属性的话,则可以使用“this.属性”的操作形式。看一下代码:
public class TestDemo1 { /** * @param args */ public static void main(String[] args) { Person pre = new Person("张三", 23); System.out.println(pre.getInfo()); } } class Person { private String name; private int age; public Person(String name, int age) { // n = name, a = age,与类中的属性同名 this.name = name; // 此时操作的是类中的属性name this.age = age; // 此时操作的是类中的属性age } public String getInfo() { return "姓名:" + this.name + " 年龄:" + this.age; // 为了代码的规范都加上this关键字 } }
输出结果:姓名:张三 年龄:23 // 没有问题 |
建议:在以后的开发之中,方法里面肯定会有参数,也会使用到类中的属性,为了更好的区分,以后只要是类中的属性都必须在前面加上"this"关键字。
1.2 表示调用方法
如果现在要想明确的表示出调用的是类中方法的话,则使用"this.方法名()"的形式,但是对于方法的调用在Java中是分为两种的:一种是普通方法、另外一种是构造方法。
如果现在希望在一个类之中完成构造方法的互调用,则可以使用"this"的操作形式,里面可以根据需要传递若干个参数。
例:现在类中有三个构造方法,但是这三个构造方法不管调用哪一个,都要执行一段固定的输出“一个新的实例化对象产生”,代码可以这样写,如下:
public class TestDemo1 { /** * @param args */ public static void main(String[] args) { Person pre = new Person("张三", 23); System.out.println(pre.getInfo()); } } class Person { private String name; private int age; public Person(){ System.out.println("一个新的实例化对象产生"); // 重复代码 } public Person(String name){ System.out.println("一个新的实例化对象产生"); // 重复代码 this.name = name; // 重复代码 } public Person(String name, int age) { System.out.println("一个新的实例化对象产生"); // 重复代码 this.name = name; // 重复代码 this.age = age; } public String getInfo() { return "姓名:" + this.name + " 年龄:" + this.age; } } 输出结果: 一个新的实例化对象产生 姓名:张三 年龄:23 |
但是,以上的实现手段存在了重复代码;那么,我们可以使用"this"关键字来减少重复代码。如下:
public class TestDemo1 { /** * @param args */ public static void main(String[] args) { Person pre = new Person("张三", 23); System.out.println(pre.getInfo()); } } class Person { private String name; private int age; public Person(){ System.out.println("一个新的实例化对象产生"); } public Person(String name){ this(); // 调用本类的无参构造方法 this.name = name; } public Person(String name, int age) { this(name); // 调用有一个参数的构造方法 this.age = age; } public String getInfo() { return "姓名:" + this.name + " 年龄:" + this.age; } } 输出结果: 一个新的实例化对象产生 姓名:张三 年龄:23 |
使用"this"关键字有一下几点需要注意:
·使用"this"调用构造方法的操作,只能放在类中构造方法的首行;如果不放在首行则会出现以下错误提示:Constructor call must be the firststatement in a constructor。
·一个类中虽然可以使用"this"进行构造方法的互调用,但是一定要保留一个构造方法,是不使用"this"调用的,以作为程序的出口;如果都使用了构造方法,则成为了递归构造调用,错误提示:Recursive constructor invocation。
1.3 表示当前对象
所谓的当前对象指的是当前正在调用类中方法的对象,
public class TestDemo1 { public static void main(String[] args) { Person pre = new Person(); System.out.println(pre); // 直接打印对象 } } class Person {
}
输出结果:Person@7692ed85 // 是一串的地址信息 |
程序的输出结果是直接输出了对象的信息“ Person@7692ed85”,默认的对象打印就是地址信息,不同的实例化对象地址信息也肯定不一样。
例:下面程序的输出结果是?
public class TestDemo1 { public static void main(String[] args) { A a = new A(); // 1、调用构造方法 } } class A { private B var; public A() { // 2、执行此构造方法 this.var = new B(this); // 3、实例化B类对象,this = a this.var.get(); // 6、通过B类对象var调用类的get()方法 } public void print() { System.out.println("Hello World !"); // 8、最后执行输出 } } class B { private A temp; public B(A temp) { // 4、执行此构造方法,这个时候temple = a this.temp = temp; // 5、将外部的a的实例给了B的temp属性 } public void get() { this.temp.print(); // 7、通过A的对象temp调用A的print()方法 } }
输出结果:Hello World ! |