三、包装类(引用类型)

 

包装类的引入

 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. 返回指定
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值