Java中static与this解析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Hong_A/article/details/74059115

一、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("[第二个静态代码块]");
    }
}

运行结果:

说明: 根据运行结果来看,静态代码块和静态变量的运行要先于构造器。

如有错误或不足,欢迎留言指正!

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页