首页 > 编程 > Java > 正文

Java的那些坑(一)

2019-11-11 02:28:52
字体:
来源:转载
供稿:网友

1,== 和equals 基本数据类型,保存在栈中,用==进行数值判断。 而引用数据类型比如Object,对象实体保存在堆中,对象引用地址保存在栈中,则==用来比较地址是否相等,而equals通过看底层源码发现

/** * Compares this string to the specified object. The result is {@code * true} if and only if the argument is not {@code null} and is a {@code * String} object that rePResents the same sequence of characters as this * object. * * @param anObject * The object to compare this {@code String} against * * @return {@code true} if the given object represents a {@code String} * equivalent to this string, {@code false} otherwise * * @see #compareTo(String) * @see #equalsIgnoreCase(String) */ public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } return false; }

默认也是比较对象的地址是否相等,String类型的可以比较对对象的内容是否相等,equals和hashcode是子类可以重写的方法,子类可以根据自己的具体业务重写达到业务的需求。String类型的数据会涉及到jvm编译时优化问题比如下列

package com.sparkhuu.base;public class StringTest { public static void main(String[] args) { String s1 = "a" + "b" + 1; // 编译时自动优化为:"ab1" String s2 = "ab1"; // == 当比较基本数据类型时,比较数值,当比较引用数据类型时,比较引用地址 System.out.println(s1 == s2); // equals 默认比较对象的地址, 可被重写,String已经重写了equals方法 System.out.println(s1.equals(s2)); String a = "1"; final String testA = "1"; String b = a + "2" + 3; // 编译时不会优化 b,c不是同一个对象,但b,c值相同 String重写了equals方法 String c = "123"; String testB = testA + "2" + 3; System.out.println(testB == c); System.out.println(testB.equals(c)); System.out.println(b == c); System.out.println(b.equals(c)); String eString = "a"; String fString = eString + "b"; String gString = "ab"; String hString = new String(gString);// 通过new的都只有在运行时才能确定 System.out.println(fString == gString); System.out.println(hString == gString); System.out.println(hString.intern() == gString.intern()); } }

结果为

truetruetruetruefalsetruefalsefalsetrue

2,基本数据类型的封装类 int –> Integer char –> Character double –>Double等 这里会涉及到装包和拆包 如下测试

package com.sparkhuu.base;public class BaseNumberTest { public static void main(String[] args) { Integer a = 1; Integer b = 1; Integer e = -127; Integer f = -127; // Integer.valueOf(); [-128 127]之前是被cache的 所以是同一个对象 而其他范围会new Integer() 所以不是同一个对象 Integer c = 200; Integer d = 200; System.out.println(a == b); System.out.println(e == f); System.out.println(c == d); char x = '中'; char x1 = 'a'; byte y = 'a'; Boolean tr = true; Boolean shBoolean = true; System.out.println(tr == shBoolean); }}

结果为

truetruefalsetrue

主要原因是基本数据类型转化为封装类的时候会调用封装类的init,而封装类的部分代码进行了cache, Integer,Short,Long的cache范围是-128到127,其中Integer可以通过配置修改范围,而Short和Long则不行。 Boolean 的cache范围是true, false, Characher全部缓存 Double,Float没有缓存。


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表