包装类的引入
Java是一个面向对象的编程语言,但是Java中的八种基本数据类型却是不面向对象的,为了使用方便和解决这个不足,在设计类时为每个基本数据类型设计了一个对应的类进行代表,这样八种基本数据类型对应的类统称为包装类(Wrapper Class),包装类均位于java.lang包。
包装类的分类

| 基本数据类型 | 包装类 |
| boolean | Boolean |
| char | Character |
| byte | Byte |
| int | Integer |
| short | Short |
| long | Long |
| float | Float |
| double | Double |
包装类和基本数据的转换
在jdk1.5之前,使用手动装箱和手动拆箱
在jdk1.5之后,使用自动装箱 和自动拆箱(自动装箱底层调用的是ValuesOf方法)
举例interger (其他包装类类似)
public class Integer01 {
public static void main(String[] args) {
//演示 int <--> Integer 的装箱和拆箱
//jdk5 前是手动装箱和拆箱
//手动装箱 int->Integer
int n1 = 100;
Integer integer = new Integer(n1);
Integer integer1 = Integer.valueOf(n1);
//手动拆箱
//Integer -> int
int i = integer.intValue();
//jdk5 后,就可以自动装箱和自动拆箱
int n2 = 200;
//自动装箱 int->Integer
Integer integer2 = n2; //底层使用的是 Integer.valueOf(n2)
//自动拆箱 Integer->int
int n3 = integer2; //底层仍然使用的是 intValue()方法
}
}
valueOf方法的底层

public class WrapperVSString {
public static void main(String[] args) {
//包装类(Integer)->String
Integer i = 100;//自动装箱
//方式 1
String str1 = i + "";
//方式 2
String str2 = i.toString();
//方式 3
String str3 = String.valueOf(i);
//String -> 包装类(Integer)
String str4 = "12345";
Integer i2 = Integer.parseInt(str4);//使用到自动装箱
Integer i3 = new Integer(str4);//构造器
System.out.println("ok~~");
}
}
package 包装类;
public class Intege {
public static void main(String[] args) {
//面试题
Object obj1 = true ? new Integer(1):new Double(2.0);
System.out.println(obj1);//1.0
//考察三元运算符,若obj1为真,应该输出1.0,而不是1
//例题一
Integer i1 = new Integer(127);
Integer i2 = new Integer(127);
System.out.println(i1 == i2); //F
//例题二
Integer i3 = new Integer(128);
Integer i4 = new Integer(128);
System.out.println(i3 == i4);//F
//例题三
Integer i5=127;
Integer i6 =127;
System.out.println(i5 == i6); //T
//例题四
Integer i7 =128;
Integer i8 =127;
System.out.println(i7 == i8); //F
//例题五
Integer i9 = 128;
Integer i10 = new Integer(127);
System.out.println(i9 == i10);//F
//例题六
Integer i11 =127;
int i12 = 127;
System.out.println(i11 == i12);//T
//例题七
Integer i13 = 128;
int i14 = 128;
System.out.println(i13 ==i14);//T
//Integer例题
Integer m=1; Integer n1 =1;
System.out.println(m == n1); //T
Integer m2 =128; Integer n2 =2;
System.out.println(m2 == n2); //F
//如果n在(-128 ---127)之间,直接从数组中返回
//如果不在这个范围内,就直接new integer(n)判断地址
}
}
String类
理解:String对象用于保存字符串,也就是一组字符序列
字符串常量对象是用双引号括起来的字符序列
字符串的字符使用Unicode字符编码,一个字符占两个字节
String类较常用构造器
1)String s1 = new String();
2)String s2 = new String(String original);
3)String s3 = new String(char[] a);
4)String s4 = new String(char[],int startdex,int count)
5)String 类实现了接口 Serializable【String 可以串行化:可以在网络传输】
接口 Comparable [String 对象可以比较大小]
6) String 是 final 类,不能被其他的类继承
7) String 有属性 private final char value[]; 用于存放字符串内容
8) 一定要注意:value 是一个 final 类型, 不可以修改(需要功力):即 value 不能指向
新的地址,但是单个字符内容是可以变化
public class String01 {
public static void main(String[] args) {
// 创建一个内容为字符数组的字符串
char[] charArray = new char[]{'D', 'E', 'F'};
String str3 = new String(charArray);
String C ="'D'"+"'E'"+"'F'";
System.out.println(C);
}
}
创建StrIng对象的两种方式
1)方式一:直接赋值 String s ="lla"
理解:先从常量池查看是否有lla数据空间,如果有直接指向,如果没有重现创建,然后指向。s 最终指向的是常量池的空间地址。
2)方式二: 调用构造器 String s2 =new String("lla");
理解:先在堆中创建空间,里面维护了value属性,指向常量池的lla,若干常量池没有lla,重新创建,如果有,直接通过value指向。最终指向的是堆中的空间地址

了解了上面的图 现在来做一下下面的题,看是否能做对呢?
equals和 == 的区别(重要)
package 包装类;
public class equals {
public static void main(String[] args) {
Integer integer1 = new Integer(1000);
Integer integer2 = new Integer(1000);
System.out.println(integer1 == integer2);//F
System.out.println(integer1.equals(integer2));//T
String a = "lla";
String b = new String("lla");
String c = new String("lla");
System.out.println(b == c);//F
System.out.println(b.equals(c));//T
System.out.println(a.equals(b));//T
System.out.println(a == b);//F
System.out.println(a == b.intern());//T
System.out.println(b == b.intern());//F
//知识点:调用Intern方法时,如果池中已经包含一个等于此String对象的字符串
//则返回池中的字符串,否则,将String对象加载到池中,并返回String对象的引用
//理解: b.intern()方法最终返回的是常量池的地址(对象)
}
}
我们再来看两道面试题
package 包装类;
public class String面试题 {
public static void main(String[] args) {
//1.下题创建几个对象? //一个
String x = "hello"+"abc";
//编译器做一个优化,判断创建的常量池对象,是否有引用指向
//String x ="hello" + "abc"; ===>String x ="helloabc";
//2.问下题创建了几个对象? //三个
String a ="hello";
String b ="abc";
String c = a + b;
//底层为:
//StringBuilder sb = new StringBuilder();
//sb.append(a);
//sb.append(b);
//sb是在堆中,并且append是在原来的字符串的基础上追加的
String d = "helloabc";
System.out.println(c == d);//真还是假? 是false
String e = "hello" + "abc";//直接看池, e指向常量池
System.out.println(d == e);//真还是假? 是true
//3.比较内容
Person p1= new Person();
p1.name ="lla";
Person p2 = new Person();
p2.name ="lla";
System.out.println(p1.name.equals(p2.name));//T 内容是否相同
System.out.println(p1.name == p1.name);//T 都在常量池中指向一个lla
System.out.println(p1.name == "lla");//T
String s1 =new String("abcd");
String s2 =new String("abcd");
System.out.println(s1 == s2);//F 比较的是s1和s2堆中的地址是否相同
}
看看老韩分析的这一道题 ,比较难

上图解析:
首先列出框架 栈 堆 和常量池
1)在实例化对象的时候,有两个属性 栈中的ex实例化对象指向堆中的str,str的value值指向常量池中的hsp 第二个属性是栈中的ex实例化对象指向堆中的ch数组,ch数组在堆中开辟新的空间存放java。
2)当调用ex.change的时候,栈先创建一个新栈,指向堆中的str,str的value值还是指向常量池中的hsp。 还指向堆中的ch数组,指向堆中存放的数组
3)当使用str =“java"时,因为不是this.str,所以新栈断开了与堆中的str,直接在常量池中创建了”java“常量 。 当使用ch[0] = 'h'时,堆中数组的第一个元素变为h
4)当调用方法完成时,ex指向的还是原先堆中的str,对应常量池里的值还是hsp,但是指向数组从java改成了hava。
5)因此 ,本题输出的是hsp and hava
String方法
1.equals 方法:比较字符串大小 2.equalsIgnoreCase 忽略大小写 判断内容是否相等 3. length 返回此字符串s1的长度 4. indexOf 返回指定字符ch在字符串中第一次出现位置的索引 5. 返回指定

1098

被折叠的 条评论
为什么被折叠?



