java设计的时候,为什么对于
String, Integer,Double,BigDecimal
这种类型的数据,不默认用==来进行值的比较呢?
对于这些类型的东西,我觉得几乎所有的比较都是
比较值啊,有什么特殊情况需要比较地址啊,
对于这几种类型,java设计的时候就直接用==来判断值
是否相等不是很好吗,为啥非要设计成必须用equals来比较,
用==会出现比较不正确的情况,这是个啥想法? 为什么设计成这样呢?
String, Integer,Double,BigDecimal
这种类型的数据,不默认用==来进行值的比较呢?
对于这些类型的东西,我觉得几乎所有的比较都是
比较值啊,有什么特殊情况需要比较地址啊,
对于这几种类型,java设计的时候就直接用==来判断值
是否相等不是很好吗,为啥非要设计成必须用equals来比较,
用==会出现比较不正确的情况,这是个啥想法? 为什么设计成这样呢?
个人觉得这个不统一很容易让人弄错
java里 == 都是比地址
equals不重写是直接调用的 ==
想比较值的话自己重写equals方法,容易记住
比如2个字符串对象
String s1 = new String("str");
String s2 = new String("str");
如果用==号比较,会返回false,因为创建了两个对象,他们在内存中地址的位置是不一样的。equals的情况比较复杂,它是java.lang.Object类中的一个方法。因为java中所有的类都默认继承于Object,所以所有的类都有这个方法。在Object类源码中是这样写的。
public boolean equals(Object obj) {
return (this == obj);
}
他同样使用==号进行内存地址的比较。但是许多java类中都重写了这个方法,比如String。
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}String里的方法,如果==号比较不相等,还会进行一下值的比较。
所以equals方法具体的作用要看当前的那个类是如何实现重写父类中该方法的。如果没有重写该方法,那么他和==号等价。
int i = 1;
int j = 1;
i == j 为true,因为值相同。Integer i = new Integer(1);
Integer j = new Integer(1);
i == j 为false,因为i和j的值不同。所需要区分的是,基本类型变量的值和引用类型变量的值是什么含义。认识到引用变量的值和对象的不同,也就理解了。
2.lz所说的如上基本类型的包装类也都重写了Object的equals,请区分父类的equals和这些子类的equals有何不同。object的equals是要比较两个对象的值之外还要看两个对象引用的内存地址是否相等的。但是,例如String它的equals是重写了object的equals的,String的equals是只比较值的,而不会看地址是否再相等。
==操作比较的是两个变量的值是否相等,对于引用类型变量表示的是两个变量在在堆中存储的地址是否项目,即栈中的内容是否项目。
equals操作表示的两个变量是否是对同一对象的引用,即堆中的内容是否相同。
==比较的是2个对象的地址。而equals比较的是2个对象的内容。
建议你两点:1.Java的数据类型。2.数据结构的存储方,即堆和栈。要弄透。。
对于这几种对象我也明显是要比较值啊,并不是想去比较对象啊。
这种设计是不是因为java不支持运算符重载导致的呢?
如果支持运算符重载,是不是就可以对于这几个类设计成用==也是去比较值?c#里是对于这几种东西==是按值比较的,这明显更符合理性吧。
你这个例子是不对的,你可以试一下,对于1的Integer用==比较会返回true的,
哈哈,迷惑了吧,事实上说是有个128的界限,128以内的Integer用==比较会返回true,
超过128才返回false,所以说java关于这个的比较很神奇,干嘛不用==直接比较值多好,
果然还是因为不支持运算符重载吗??
如果知道下面的规则,你对上面例子的输出结果或许就不会那么疑惑了:
1. 对于基本类型,==将比较两边的值是否相等;
2. 对于对象,==则比较对象的是否指向同一个对象。
如果你仍然对输出结果不甚明白,那么别急,关于Java堆与栈的介绍将会让你明了,但是在这里我还要添加关于equals()的介绍。
或许你已经被告知,要想比较对象的实际内容是否相同必须使用所有对象都适用的特殊方法equals(),例如:Integer n1=new Integer(13);
Integer n2=new Integer(13);
System.out.println(n1.equals(n2)); //true这看上去的确很简单,但是下面的例子中equals()又要让你失望和疑惑了:
public class Value { public int i;}
Value v1=new Value();
Value v2=new Value();
v1.i=v2.i=13;
System.out.println(v1.equals(v2)); //false
哦,它输出了false!好吧,让我们看看equals()方法的原型:view plaincopy to clipboardprint?
public boolean equals(Object obj) {
return (this == obj);
} 再让我们看看Integer中的equals()方法:view plaincopy to clipboardprint?
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
} OK!一切都清楚了,继承自Object中的equals()方法与==没什么两样,只是Integer类对equals()方法进行了重写而已,这样我们很容易能写出令上面例子中System.out.println(v1.equals(v2));语句输出true的方法献给Java初学者