关于Android中this的用法解释
问题由来
由于很多同学在学习Android时候没有对Java有很深的了解,很多人都会对代码中各种各样的this产生疑惑。
以《第一行代码Android》P37页,P43页代码为例:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.first_layout);
Button button1 = (Button) findViewById(R.id.button_1);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
}
});
}
有些同学会觉得非常奇怪,这个this是用来指代什么呢?是和class一样的意思吗?
那为什么FirstActivity要用this,而SecondActivity却要用class呢?
this的三种用法
1.表示对当前对象的引用
以以下代码为例:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button play = (Button) findViewById(R.id.play);
Button stop = (Button) findViewById(R.id.stop);
play.setOnClickListener(this);
stop.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.play:
Videoplay();
break;
case R.id.stop:
Videostop();
break;
}
}
}
play.setOnClickListener(this)中的this,是对当前类MainActivity的引用。
那么为什么在开始的代码中要使用FirstActivity.this来引用FirstActivity呢?我们仔细分析上下两段代码,发现this所处的类是不一样的,上面的代码中,this存在于匿名类View.OnClickListener()中!
匿名类View.OnClickListener()是FirstActivity的内部类,如果我们在内部类中使用this,他所引用的类应该是View.OnClickListener()。
Android编译器在编译我们的代码的时候就会发现:“诶View.OnClickListener()你丫谁啊?我咋从你身上启动SecondActivity啊”。然后就快乐的报错了。
所以在内部类中,如果我们需要获得其外部类,就要使用“外部类.this”的写法。
- 注:“.class”是因为表示其它类的写法。
2.表示用类的成员变量,而非函数参数
以以下代码为例:
public class Book {
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
在代码中我们定义了一个Book类并生成了对应的getter和setter方法。在setter方法中我们发现了this,而且还是this.而不是.this!
仔细研究setId方法,我们发现里面的几个id所对应的东西都是不一样的。setId(int id)中的id指的是外部调用这个方法时所赋予的参数,比如新建一个Book类变量book,book.setId(1)中的1就是参数。
this.id中的id我们显然希望他是Book类中的成员变量id,=id中的id显然应该是赋予的参数,和setId(int id)为同样的东西。
故而这个this就是为了防止编译器把三个id都认为是同样的东西,特地指明了第二个this是Book类中的成员变量id。
- 有些同学可能会和第一个用法中的this混淆,认为this不是指向setId方法吗?这说明你混淆了类和方法之间的区别。this指向的是类而不是方法。
3.用于在构造方法中引用满足指定参数类型的构造器
这个说法可能有些复杂,因为这个主要是用在Java中的,Java中一个方法可能对应多种构造方法,如:
public class Student
public Student()
}
public Student(String name)
}
public Student(int id)
}
}
以方便我们减少方法的数量,那么如果我们修改上述代码变为:
public class Student
public Student() {
this(“HelloWorld”);
}
public Student(String name) {
}
public Student(int id) {
}
}
this又出现了,这次this出现在了构造方法之中,这意味着当你不使用参数调用Student类时,编译器会自动认为你使用了“HelloWorld”参数调用了Student类中的Student(String name)的构造方法,如果改成this(1)的话那就是Student(int id)的构造方法.
- 注:第三种用法,每个构造方法只能引用一个构造方法!而且必须位于起始位置。
public class Student
public Student() {
this(“HelloWorld”);
}
public Student(String name) {
this(1);
}
public Student(int id) {
}
}
这是符合规范的,无论你使用Student()还是Student(“...”),都等于Student(1);
public class Student
public Student() {
this(“HelloWorld”);
this(1);
}
public Student(String name) {
}
public Student(int id) {
}
}
这是错误的,你使用Student()时编译器会不知道到底应该使用Student(“HelloWorld”)还是Student(1)而选择死亡。