如果一个类有两个不同的对象,那么这两个对象都可以调用到类里的某个方法。但是,它是如何知道是哪个对象在调用这个方法的呢?看下面的代码:
public class Dog {
void bark() {
System.out.println("bark");
}
}
public class DogMain {
public static void main(String[] args) {
Dog dogA, dogB;
dogA = new Dog();
dogB = new Dog();
dogA.bark();
dogB.bark();
}
}
虽然,给两个对象分别命名为dogA和dogB,但是,对于Dog类来说,当bark()方法被调用的时候,它本应该是不知道谁在调用这个方法的。但事实却是它明确的知道是哪个对象在调用方法,那么这是怎样实现的呢?
其实是编译器在幕后做了一些工作,在bark()放法被调用的时候,它暗自把所操作对象的引用作为第一个参数传递给bark(),所以,上述两个对象在调用方法的时候就变成了这样
dogA.bark(dogA);
dogB.bark(dogB);
当想要在方法内部使用当前对象的引用的时候,由于这个引用是编译器偷偷传入的,所以并没有明确的标识符可用。但是为此有个专门关键字来使用:this。在方法内部使用this关键字的时候和其他对象的引用并无不同。需要注意的是,在同一个类的内部方法之间的相互调用不必通过this关键字,可以直接使用。
public class Dog {
void bark() {
System.out.println("bark");
}
void run() {
bark();
}
}
在run()内部也可以写成this.bark(),但通常并没有这样的必要,编译器会自动帮我们添加。只有在明确需要指出对当前对象的引用的时候,才需要使用this关键字,例如,当需要在在一个方法里返回当前对象的引用时,就可以在return的返回值里这样写:
public class Dog {
Dog eat() {
System.out.println("吃狗粮");
return this;
}
}
有时候在一个类的内部会有多个构造方法,构造方法之间的相互调用也可以用过this关键字来实现。并且,如果构造方法带有不同的参数,那么也可以为this指定不同的参数以明确对符合参数列表的构造方法的调用
public class Dog {
public Dog() {
this("小明");
}
public Dog(String name) {
this(name, 40);
}
public Dog(String name, int weight) {
}
}
平时写代码时调用一个类里的方法或者变量,一般是两种方式
- 对象的引用.方法名
对象的引用.变量名 - 类名.静态方法名
类名.静态变量名
代码更清晰
public class Dog {
static int sValue;
int mValue;
static void jump() {
System.out.println("jump");
}
void bite() {
System.out.println("bite");
}
}
public class DogMain {
public static void main(String[] args) {
Dog dog = new Dog();
dog.mValue = 1;
dog.bite();
Dog.jump();
Dog.sValue = 2;
}
}
由这两种调用方式,就可以明白了为什么能在类的内部可以通过this.变量名(方法名)的方式直接用方法或者变量了。因为,this此刻代表的是对当前对象的引用,这就符合了上文提到的两种方式的第一种方式。
同时,也知道了为什么以下的写法会报错
报错的信息描述是'Dog.this' cannot be referenced from a static context
这个报错信息简单点的描述就是不能把一个非静态变量赋值给一个静态变量,由于this代表的是一个当前对象的引用,而此引用在实例化的时候并不知道它是否是静态,但是此时的变量dog是明确声明为了static,因此不能通过this给静态变量赋值
网友评论