this与super关键字总结
Ⅰ.this
用类名定义一个变量的时候,定义的应该只是一个引用,外面可以通过这个引用来访问这个类里面的属性和方法。类里面也有一个引用来访问自己的属性和方法,这个引用就是 this 对象,它可以在类里面来引用这个类的属性和方法。
每当一个对象创建后,Java虚拟机会给这个对象分配一个引用自身的指针,这个指针的名字就是 this。因此,this只能在类中的非静态方法中使用,静态方法和静态的代码块中绝对不能出现this的用法。
this主要要三种用法:
- 在类的方法定义中使用的this关键字代表调用该方法对象的引用。(this关键字只能在方法内部使用;只有当需要明确指出当前对象的引用时,才使用this关键字)
- 表示用类的成员变量,而非函数参数,注意在函数参数和成员变量同名是进行区分!其实这是第一种用法的特例,比较常用,所以拿出来强调一下。
- 将当前的对象传递给其他方法。
- 用于在构造方法中引用满足指定参数类型的构造器(其实也就是构造方法)。但是这里必须非常注意:只能引用一个构造方法且必须位于开始!
示例程序:
eg1
1 public class ThisDemo { 2 int number = 0; 3 ThisDemo increment(){ 4 number++; 5 return this; 6 } 7 private void print(){ 8 System.out.println("number="+number); 9 } 10 public static void main(String[] args) { 11 ThisDemo tt=new ThisDemo(); 12 tt.increment().increment().increment().print(); 13 } 14 } 15 /*Output: 16 i = 3 17 *///:~
可以看到,通过this关键字可以很容易在一条语句里面对同一个对象执行多次操作。
eg2 将当前的对象传递给其他方法
1 //: initialization/PassingThis.java 2 3 class Person { 4 public void eat(Apple apple) { 5 Apple peeled = apple.getPeeled(); 6 System.out.println("Yummy"); 7 } 8 } 9 10 class Peeler { 11 static Apple peel(Apple apple) { 12 // ... remove peel 13 return apple; // Peeled 14 } 15 } 16 17 class Apple { 18 Apple getPeeled() { return Peeler.peel(this); } 19 } 20 21 public class PassingThis { 22 public static void main(String[] args) { 23 new Person().eat(new Apple()); 24 } 25 } /* Output: 26 Yummy 27 *///:~
Apple需要调用Peeler.peel()方法,它是一个外部的工具方法,将执行由于某种原因而必须放在Apple外部的操作。为了将其自身传递给外部方法,Apple必须使用this关键字。
eg3 在构造方法中引用满足指定参数类型的构造器
1 //: initialization/Flower.java 2 // Calling constructors with "this" 3 import static net.mindview.util.Print.*; 4 5 public class Flower { 6 int petalCount = 0; 7 String s = "initial value"; 8 Flower(int petals) { 9 petalCount = petals; 10 print("Constructor w/ int arg only, petalCount= " 11 + petalCount); 12 } 13 Flower(String ss) { 14 print("Constructor w/ String arg only, s = " + ss); 15 s = ss; 16 } 17 Flower(String s, int petals) { 18 this(petals); 19 //! this(s); // Can't call two! 20 this.s = s; // Another use of "this" 参数s和数据成员s的名字相同,用this.s来避免歧义。 21 print("String & int args"); 22 } 23 Flower() { 24 this("hi", 47); 25 print("default constructor (no args)"); 26 } 27 void printPetalCount() { 28 //! this(11); // Not inside non-constructor! 29 print("petalCount = " + petalCount + " s = "+ s); 30 } 31 public static void main(String[] args) { 32 Flower x = new Flower(); 33 x.printPetalCount(); 34 } 35 } /* Output: 36 Constructor w/ int arg only, petalCount= 47 37 String & int args 38 default constructor (no args) 39 petalCount = 47 s = hi 40 *///:~
构造器Flower(String s, int petals)表明:尽管可以用this调用一个构造器,但却不能调用两个。此外,必须将构造器调用置于最起始位置处,否则编译器会报错。
printPetalCount()方法表明,除构造器之外,编译器禁止在其他任何方法中调用构造器。
Ⅱ.super
super的使用和this基本相同,现在写下两者之间的比较:
1.super()从子类中调用父类的构造方法,this()在同一类内调用其它方法。
2.this和super不能同时出现在一个构造函数里面。
3.super()和this()均需放在构造方法内第一行。
4.this()和super()都指的是对象,所以,均不可以在static环境中使用。
另外1.在构造器中this或super必须放在第一行
另外2(static的含义)
了解this关键字之后,就能更全面的理解static方法的含义。static方法没有this的方法。在static方法的内部不能调用非静态方法,但反过来可以。可以在没有创建任何对象的前提下,仅仅通过类本身来调用static方法。但这实际上正是static方法的主要用途。Java中禁止使用全局方法,但通过在类中置入static方法就可以访问其他static方法和static域。