0024 Java学习笔记-面向对象-包装类、对象的比较、String常量池问题
public class T1{
public static void main(String[] args) {
Integer inObj=13; //自动装箱
Object boolObj=true; //自动装箱,基本类型赋值给Object类型变量
int i=inObj; //自动拆箱
float f=inObj; //自动拆箱,注意类型匹配
System.out.println(i);
System.out.println(f);
if (boolObj instanceof Boolean) {
boolean b=(Boolean)boolObj; //强制类型转换+自动拆箱
System.out.println(b);
}
}
}
public class Test{
public static void main(String[] args) {
String strByte="127";
String strShort="32767";
String strInt="2147483647";
String strLong="21474836478"; //加了L,用parse和new转,都会失败
String strFloat="3.1415F"; //加了F,用parse和new转,都能成功
String strDouble="3.5665956565";
String strBoolean="true";
byte b1=Byte.parseByte(strByte);
byte b2=new Byte(strByte);
System.out.println(b1+" "+b2);
short s1=Short.parseShort(strShort);
short s2=Short.parseShort(strShort);
System.out.println(s1+" "+s2);
int i1=Integer.parseInt(strInt);
int i2=new Integer(strInt);
System.out.println(i1+" "+i2);
long l1=Long.parseLong(strLong);
long l2=new Long(strLong);
System.out.println(l1+" "+l2);
float f1=Float.parseFloat(strFloat);
float f2=new Float(strFloat);
System.out.println(f1+" "+f2);
double d1=Double.parseDouble(strDouble);
double d2=new Double(strDouble);
System.out.println(d1+" "+d2);
boolean boo1=Boolean.parseBoolean(strBoolean);
boolean boo2=new Boolean(strBoolean);
System.out.println(boo1+" "+boo2);
}
}
输出
127 127
32767 32767
2147483647 2147483647
21474836478 21474836478
3.1415 3.1415
3.5665956565 3.5665956565
true true
public class Test{
public static void main(String[] args) {
System.out.println(String.valueOf(127));
System.out.println(String.valueOf(32767));
System.out.println(String.valueOf(2147483647));
System.out.println(String.valueOf(21474836478L)); //注意L
System.out.println(String.valueOf(3.1415F)); //注意F
System.out.println(String.valueOf(3.5665956565));
System.out.println(String.valueOf(true));
}
}
输出如下:
127
32767
2147483647
21474836478 //注意没有L
3.1415 //注意没有F
3.5665956565
true
public class Test{
public static void main(String[] args) {
System.out.println(new Integer(2)==new Integer(2));
System.out.println(new Integer(2).equals(new Integer(2)));
Integer i1=127;
Integer i2=127;
System.out.println("127: i1==i2? "+(i1==i2));
Integer i3=128;
Integer i4=128;
System.out.println("128: i3==i4? "+(i3==i4));
Integer i5=new Integer(127);
System.out.println("127: i1==i5? "+(i1==i5));
Integer i6=new Integer(128);
System.out.println("128: i3==i6? "+(i3==i6));
}
}
输出如下:
false
true
127: i1==i2? true
128: i3==i4? false
127: i1==i5? false
128: i3==i6? false
public class Test{
public static void main(String[] args) {
System.out.println(Boolean.compare(true,false));
System.out.println(Boolean.compare(new Boolean(false),true));
System.out.println(Integer.compare(5,13));
System.out.println(Integer.compare(new Integer(19),new Integer(10)));
}
}
class Person{
private String name;
private String id;
Person(){}
Person(String name,String id){
this.name=name;
this.id=id;
}
public boolean equals(Object obj){
if (this==obj){ //如果二者指向同一个对象,返回true
return true;
}
if (obj!=null && obj.getClass()==Person.class){ //obj不为null,且指向的对象是Person类
Person perObj=(Person)obj; //类型转换
if(this.id.equals(perObj.id)){ //根据id是否相等判断两个Person对象是否相等
return true;
}
}
return false; //如果obj为null或者obj指向的对象不是Person,返回false
}
}
代码1:
String s1="AB";
String s2="A"+"B";
System.out.println(s1==s2); //true。编译阶段即可确定s2="AB",运行时,s1和s2都指向常量池的"AB"
代码2:
String s1="AB";
String s2="B";
String s3="A"+s2;
System.out.println(s1==s3); //false。s2是变量,编译阶段不能确定s3的值
代码3:
String s1="AB";
final String s2="B"; //注意多了个final
String s3="A"+s2;
System.out.println(s1==s3); //true。s2的值不可变,编译阶段就确定了s3的值是"AB"
代码4:
public static void main(String[] args) {
String s1="AB";
final String s2=getString(); //注意有final
String s3="A"+s2;
System.out.println(s1==s3); //false。虽然s2值不可变,但是是通过方法返回的,编译阶段也不能确定其值
}
static String getString(){
return "B";
}
代码5:
String s1="AB";
String s2="A";
String s3="B";
String s4=s2+s3;
System.out.println(s1==s4); //false.
代码:6
String s1="AB";
final String s2="A";
final String s3="B";
String s4=s2+s3;
System.out.println(s1==s4); //true.s4的值在编译期即可确定
代码7:开始引入intern()方法
String s1="A";
String s2="B";
String s3=s1+s2; //s3实际指向堆内存中的"AB"
System.out.println(s3==s3.intern()); //true。s3.intern()将堆内存中"AB"对象的地址添加到常量池表中,而不是在常量池中再创建个对象,二者实际都指向堆内存中的对象,因此二者相等
System.out.println(s3=="AB"); //true。s3指向堆内存中"AB"的地址;"AB"按理说应当位于常量池,但常量池中只保存了"AB"在堆内存中的地址,所有二者还是相当
//intern()方法用于将该字符串追加到常量池中,如果已经有了,就返回其引用;如果没有就将地址添加到常量池表中,再返回其引用,实际指向的是堆内存中的对象
代码8:将代码7最后两行代码换个顺序
String s1="A";
String s2="B";
String s3=s1+s2;
System.out.println(s3=="AB"); //false.s3指向堆内存中的对象,"AB"则在常量池中
System.out.println(s3==s3.intern()); //false.s3还是指向堆内存中的对象,s3.intern()返回常量池中的"AB"的地址
这点存疑
,从Java1.7开始,常量池位于堆内存