2 tianbiandetianbian tianbiandetianbian 于 2017.08.13 16:00 提问

java中this关键字的疑惑

this关键字表示当前的对象,按这种理解,下面的代码中就有点问题了,代码如下:

public class Person implements Comparable {
    private String name;
    private int age;

    public Person(String name, int i) {
        super();
        this.name = name;
        this.age = i;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public int compareTo(Object o) {
        if (o instanceof Person) {
            Person p = (Person) o;
            int temp = this.age - p.age;//这里的this.age和p.age难道不是始终相等?
            return temp == 0 ? this.name.compareTo(p.name) : temp;
        }

        return 0;
    }

}


上述代码是给Person类加一个比较功能(先比较age,如果age相同则再比较name),通过实现Coparatable接口并重写compraTo()方法来实现,但是this.age和p.age不是应该始终相等吗?因为this表示当前Person的一个对象,而p也是当前Person类的一个对象,p和this的hash值应该是相同的,怎么这里表示的意思是不同,忘大神解释下?

7个回答

Small_Mouse0
Small_Mouse0   Ds   Rxr 2017.08.13 16:44
已采纳
   public V put(K key, V value) {
        Entry<K,V> t = root;
        if (t == null) {
            compare(key, key); // type (and possibly null) check

            root = new Entry<>(key, value, null);
            size = 1;
            modCount++;
            return null;
        }
        int cmp;
        Entry<K,V> parent;
        // split comparator and comparable paths
        Comparator<? super K> cpr = comparator;
        if (cpr != null) {
            do {
                parent = t;
                cmp = cpr.compare(key, t.key);
                if (cmp < 0)
                    t = t.left;
                else if (cmp > 0)
                    t = t.right;
                else
                    return t.setValue(value);
            } while (t != null);
        }
        else {
            if (key == null)
                throw new NullPointerException();
                Comparable<? super K> k = (Comparable<? super K>) key;
            do {
                parent = t;
                                //在这里做了显示的调用
                cmp = k.compareTo(t.key);
                if (cmp < 0)
                    t = t.left;
                else if (cmp > 0)
                    t = t.right;
                else
                    return t.setValue(value);
            } while (t != null);
        }
        Entry<K,V> e = new Entry<>(key, value, parent);
        if (cmp < 0)
            parent.left = e;
        else
            parent.right = e;
        fixAfterInsertion(e);
        size++;
        modCount++;
        return null;
    }

这是我在TreeSet源码中找到的一段,,看到我注释的哪一行,,就是对你那个接口的显示调用,

     do {
                parent = t;
                                //在这里做了显示的调用
                cmp = k.compareTo(t.key);
                if (cmp < 0)
                    t = t.left;
                else if (cmp > 0)
                    t = t.right;
                else
                    return t.setValue(value);
            } while (t != null);

就是这一段,,,意思是对集合进行排序。。。

有问题还可以追问。

chenbaige
chenbaige   Rxr 2017.08.13 16:11

兄弟,不一样的,如a. compareTo(b):this指的是a,你那个p相当于指的是b。

qq_33727653
qq_33727653   2017.08.13 16:23

在楼主写的理解中“this表示当前Person的一个对象,而p也是当前Person类的一个对象”这句是错的。
重写的 compareTo(Object o)方法,在方法中this指的是compareTo这个方法的调用者,而代码中的p是你的参数对象。
也就是说this指向的是当前调用者(因为方法是这个对象调出来的,自然方法里面的this就应该指向它)这个对象而不是方法参数里的对象。
所以楼主对'this关键字表示当前的对象'中的‘当前’这俩字理解有偏差!!!

fsy351
fsy351   2017.08.13 16:23

首先你要清楚,类和对象的区别

类:是对客观事物的一种抽象表述,包含对其进行的属性和方法
对象:是类的对应的一个客体,是类实例化的一个表示,也就是说一个类可以有创造多个对象,每个对象拥有自己的属性字段信息,
对象与对象之间信息是不同的(对象属性值引用同一对象,可能相同,目前若不理解,先忽略这句),而对象之间的方法是共享的。

举个例子,比如人(Person)是一个类,可以有叫“张三”人,可以叫“李四”的人,他们都有自己的年龄(age)

一天,张三知道了李四的年龄,张三拿自己年龄(this.age)和李四去比( obj.age obj为参数 ),由于方法的是对象公用的,
也就得有方法如何表示自己,那么this就应运而生了。

以上解释可根据java的内存模型得到验证,深入理解请查阅相关资料。

Small_Mouse0
Small_Mouse0   Ds   Rxr 2017.08.13 16:05

加入调用的时候用的是:

     Persion pesion1 = new Persion("xiaowang",10); //pesion1  指的是小王,,它10岁
     Persion pesion2 = new Persion("xiaoli",12); //pesion2  指的是小李,,它12岁
        persion1.compareTo( pesion2)//此时   你所说的this指的是,,persion1,,,p指的是persion2

            persion2.compareTo( pesion1)//此时   你所说的this指的是,,persion2,,,p指的是persion1

(1)this 是当前对象,,也就是调用这个方法的对象
(2)p 是传入的对象,

我感觉已经很详细了,,有疑问还可以追问,,给个采纳,谢谢

Small_Mouse0
Small_Mouse0 我把TreeSet中调用那个接口的源码,,贴在下面了。
大约一个月之前 回复
tianbiandetianbian
tianbiandetianbian 回复小鼠标丶: 哈哈,哥们,回复不好贴代码啊,我重新自己自问自答了一个,贴了完整代码,帮忙看下呗,万分感谢!
大约一个月之前 回复
Small_Mouse0
Small_Mouse0 私信发给我吧,,,你的代码我看不到,,
大约一个月之前 回复
Small_Mouse0
Small_Mouse0 不好意思,你的完整代码我看不到,,
大约一个月之前 回复
Small_Mouse0
Small_Mouse0 哈哈,嗯,我知道,,这个接口是用来排序的,,道理是一样的,,你可以去看他的排序代码(也是用这个方法来对比两个对象谁大谁小的),,,,你的集合在排序的时候会显示的调用(排序肯定得比大小对吧)
大约一个月之前 回复
tianbiandetianbian
tianbiandetianbian 这个是主函数类:
大约一个月之前 回复
tianbiandetianbian
tianbiandetianbian 这种很显式地调用,我知道this和p所引用的对象具体是哪个,但是我的场景不是这种明显的调用,而是用TreeSet集合存储Person对象,按照age的大小来存,如果age大小相等,就按照name的字符串大小存,完整代码如下:
大约一个月之前 回复
tianbiandetianbian
tianbiandetianbian   2017.08.13 16:30

这种很显式地调用,我知道this和p所引用的对象具体是哪个,但是我的场景不是这种明显的调用,而是用TreeSet集合存储Person对象,按照age的大小来存,如果age大小相等,就按照name的字符串大小存,完整代码如下:
主函数类

import java.util.Iterator;
import java.util.TreeSet;

import com.sun.org.apache.bcel.internal.generic.NEW;

import bean.Person;

public class TreeSetTest {

public static void main(String[] args) {
    TreeSet ts = new TreeSet();
    ts.add(new Person("jy", 22));
    ts.add(new Person("ab", 23));
    ts.add(new Person("ji", 11));
    ts.add(new Person("cc", 18));
    for (Iterator it = ts.iterator(); it.hasNext();) {
        System.out.println(it.next());
    }

}

}

Person类:

public class Person implements Comparable {
private String name;
private int age;

public Person(String name, int i) {
    super();
    this.name = name;
    this.age = i;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public int getAge() {
    return age;
}

public void setAge(int age) {
    this.age = age;
}

@Override
public int compareTo(Object o) {
    if (o instanceof Person) {
        Person p = (Person) o;
        int temp = this.age - p.age;//这里的this.age和p.age难道不是始终相等?
        return temp == 0 ? this.name.compareTo(p.name) : temp;
    }

    return 0;
}

@Override
public String toString() {
    return this.name+","+this.age;
}

}

结果:
ji,11
cc,18
jy,22
ab,23

结果是按照定义的排序进行存储的,但是没有那种很明显的调用comparaTo()方法,能否解释下.(可能我需要去看底层的add()源码)

tianbiandetianbian
tianbiandetianbian 回复fsy351: 感谢,很有帮助,膜拜大神!
大约一个月之前 回复
fsy351
fsy351 给你个blog看吧,之前我看过的 http://www.cnblogs.com/lixiaolun/archive/2012/12/25/2832775.html
大约一个月之前 回复
STU756
STU756   2017.08.14 04:29

this就是指向你当前实例化的对象。你实例化一个对象,调用一个该对象的非静态方法的时候,在帧栈中的局部变量表的第一个下标的槽就是this,它指向你当前调用方法的对象。就可以通过this来操作该对象啦!

Csdn user default icon
上传中...
上传图片
插入图片