一、this关键字
1.作为当前类的实例调用实例方法或实例变量出现在方法体xxx()中:此时this的具体对象取决于调用方法xxx()的实例,但是this的类型是可以确定的——当前类
2.以this(参数)形式调用构造器方法出现在另一个重载的构造器中
3.作为当前对象值返回
4.疑问与猜测:系统何时为this分配内存空间:个人猜测隐式实例this的内存分配时间在静态代码块、静态成员变量及静态方法之后,在实例变量、实例方法即普通代码块之前。为何这样说呢?这里有一篇相关文章:浅析java中的this
/**
* 关键字‘this'的相关解析
* @author johnyhe
*
*/
public class This_Useage {
public static void main(String[] args) {
//现在来测试this在方法体中具体指向的对象
Animal animal = new Animal();
Dog dog = new Dog();
//分别调用对应的play方法,jump()方法
animal.jump();
dog.jump();
/*play()方法中调用的jump()方法的行为表现取决于实例变量(在栈
*内存)指向的对象(在堆内存)
*/
animal.play();
dog.play();
}
}
class Animal {
public Animal() {}
public void jump() {
System.out.println("Unknown animal jump");
}
/**
* 在play()方法中,this具体指的对象取决于调用play()方法的实例,
* 但是this的类型是可以确定的——即当前类的实例
*/
public void play() {
if(this.getClass() == Animal.class)
System.out.println("\nUnknown animal play:");
else if(this.getClass() == Dog.class)
System.out.println("\nA dog play:");
/**
* this用法一:在方法体中,this代表当前类的实例,可以调用该
* 类的实例变量,实例方法
* @author johnyhe
*
*/
this.jump();
// jump();//省略了this,实际上是存在的
}
}
class Dog extends Animal {
private String kind;
/**
* this用法二:在构造器中,this可以调用实例方法及实例变量,也可以
* 以:this()形式调用其他的构造器。
*/
public Dog() {
this("Dog");
}
public Dog(String kind) {
this.kind = kind;
}
public String getKind() {
return kind;
}
//返回对象的值
public Dog getDog() {
return this;
}
@Override
public void jump() {
System.out.println("A dog jump");
}
}
给出运行结果:
说明:根据运行结果来看,当animal,dog实例变量调用实例方法jump()时,二者的行为表现取决于实例变量指向的对象中的jump()方法体行为,这就是运行时多态。敲黑板!!!当animal调用play()方法时表现为父类,这个不解释;当dog调用父类方法play()时,play()中的this.jump()表现为子类Dog的jump()方法行为。此时,this具体指向的对象才确定出来。即this与实例变量dog指向的对象相同
二、static关键字
1. static用于修饰成员变量和方法,这些成员变量及方法属于类而不属于实例。
2. static可以修饰代码块,即静态代码块。静态代码块也属于类本身。
3.以上的成员变量、方法和代码块在编译期间就已经存在了。
4.由于static修饰的成员变量、方法及代码块属于类,因此其中不能使用当前类本身的内部实例this引用调用任何实例变量和实例方法,因为实例变量及方法都是在实例被创建之后才存在的。因此,如果要调用实例方法及变量则需要在其中创建实例然后调用。
5.关于static修饰的成员变量,方法的调用 :既可以用实例调用,也可以用类名调用。但是既然属于类,用类的实例调用显得有点矛盾,因此强烈建议用类名调用。
/**
* 关键字static的解析
* @author johnyhe
*
*/
public class Static_Useage {
private int value0;//实例变量
private static int value1;//成员变量(类变量)
public Static_Useage(int value0) {
System.out.println("**********进入构造器**********");
this.value0 = value0;
System.out.println("赋值后value0 = " + value0);
System.out.println("**********离开构造器**********");
}
static {
System.out.println("[第一个静态代码块]");
System.out.println("***********进入static块***********");
System.out.println("value1 = " + value1);
value1 = 2;
System.out.println("重新赋值后的value1 = " + value1);
System.out.println("***********离开static块***********");
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Static_Useage test = new Static_Useage(9);
test.method_instance();
method_static();
}
public static void method_static() {
System.out.println("调用了static方法");
}
public void method_instance() {
System.out.println("调用了实例方法");
}
static {
System.out.println("[第二个静态代码块]");
}
}
运行结果:
说明: 根据运行结果来看,静态代码块和静态变量的运行要先于构造器。
如有错误或不足,欢迎留言指正!