常用类(总结)

包装类

包装类基本知识

Java中八种基本数据类型并不是对象,是为了将基本数据类型和对象之间实现互相转化,Java为每一个基本数据类型提供了相应的包装类。

JAVA是面向对象的语言,但是并不是“纯面向对象”的,因为经常用到的基本数据类型就不是对象,在实际的操作中需要将基本数据类型转化成为对象,以便于操作。

Java在设计类时为每个基本数据类型设计了一个对应的类进行代表,这样八个和基本数据类型对应的类统称为包装类。

在八个基本数据类型中,除了Integer和Character,其它六个的类名和基本数据类型一致,首字母大写

在这里插入图片描述

Number类是抽象类,因此它的抽象方法,所有子类都需要提供实现。Number类提供了抽象方法,如图。表明了所有的“数字型”包装类都可以相互转型。
image.png

包装类的用途:
1、作为和基本数据类型对应的类型存在,方便涉及到对象的操作,如Object[],集合等等
2、包含每种基本数据类型的相关属性如最大值,最小值等。

自动装箱和拆箱

自动装箱(autoboxing)和拆箱(unboxing),将基本数据类型和包装类自动转换。

自动装箱

基本类型的数据处于需要对象的环境中时,会自动转为“对象”。
如Integer i = 10;编译器会自动的转成Integer i = Integer.valueOf(10),这就是JAVA的自动装箱。

自动拆箱

需要一个值的时候,对象会自动的转成基本数据类型,没有必要再去显式调用intValue()、doubleValue()等转型方法。
Integer i = Integer.valueOf(10); int j = i;编译器会自动转成:int j = i.intValue();这个过程就是自动拆箱。

包装类的缓存问题

整型和char类型对应的包装类,在自动装箱时,对于-128~127之间的值会进行缓存处理,目的是为了提高效率。

缓存的原理:如果数据在-128~127这个区间,类在加载的时候就已经为该区间的每个数值创建了对象,并将这256个对象存放到一个名为cache的数组中,每当自动装箱过程发生时(或者手动valueOf())时,就会先判断是否在该区间,如果在则直接获取数组中对应的包装对象的引用,如果不在该区间,则会通过new调用包装类的构造方法来创建对象。

//Integer源码片段
public static Integer valueOf(int i){
    if (i >= IntegerCache.low && i <= IntegerCache.high){
        return IntegerCache.cache[i + (-IntegerCache.low)];
    } 
    return new Integer(i);
}
/**
1. IntegerCache类为Integer类的一个静态内部类,仅供Integer类使用。由下面的源码我们可以看到,静态代码块的目的就是初始化数组cache的,这个过程
会在类加载时完成
2. 一般情况下 IntegerCache.low为-128,IntegerCache.high为127,
*/
private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);

            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() {}
 }

包装类总结

  • 自动装箱调用的是valueOf()方法,而不是new Integer()方法。
  • 自动拆箱调用的是xxxValueOf()方法。
  • 包装类在自动装箱时为了提高效率,对于-128~127之间的值会进行缓存处理,超过范围后,对象之间不能再使用==进行数值比较,应该使用equals方法。

字符串类

String类代表不可变的字符序列(final),StringBuilder和StringBuffer类代表可变字符序列。

String类对象是不可变的Unicode字符序列,不可变对象指的是,对象内部的成员变量的值无法再修改。

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    
    /** The value is used for character storage. */
    private final char value[];
    /**
    字符串内容全部存储到 value[ ]数组中,而变量 value 是 final 类型的,也就
    是常量(即只能被赋值一次)。 这就是“不可变对象”的典型定义方式
    */
}

String 类的简单使用

/**
substring()是对字符串的截取操作,
但本质是读取原字符串内容生成了新的字符串
*/
public static void main(String[ ] args) {
        String s1 = new String("abcdef");
        String s2 = s1.substring(2, 4);
        // 打印:ab199863
        System.out.println(Integer.toHexString(s1.hashCode()));
        // 打印:c61, 显然 s1 和 s2 不是同一个对象
        System.out.println(Integer.toHexString(s2.hashCode()));
}
/**
在遇到字符串常量之间的拼接时,编译器会做出优化,即在编译期间就会完成字符串的
拼接。
*/
 public static void main(String[ ] args) {
        //编译器做了优化,直接在编译的时候将字符串进行拼接
        String str1 = "hello" + " java";//相当于 str1 = "hello java";
        String str2 = "hello java";
        System.out.println(str1 == str2);//true
        String str3 = "hello";
        String str4 = " java";
        //编译的时候不知道变量中存储的是什么,所以没办法在编译的时候优化
        String str5 = str3 + str4;
        System.out.println(str2 == str5);//false
}

StringBuffer和StringBuilder

StringBuffer和StringBuilder都是可变的

  • StringBuffer 线程安全,做线程同步检查,效率较低
  • StringBuilder 线程不安全,不做线程同步检查,效率较高。推荐使用
常用的方法

重载的 **public **StringBuilder append(…)方法
可以为该 StringBuilder 对象添加字符序列,仍然返回自身对象。
方法 **public **StringBuilder delete(**int **start,**int **end)
可以删除从 start 开始到 end-1 为止的一段字符序列,仍然返回自身对象。
方法 **public **StringBuilder deleteCharAt(**int **index)
移除此序列指定位置上的 char,仍然返回自身对象。
重载的 **public **StringBuilder insert(…)方法
可以为该 StringBuilder 对象在指定位置插入字符序列,仍然返回自身对象。
方法 **public **StringBuilder reverse()
用于将字符序列逆序,仍然返回自身对象。
方法 **public **String toString() 返回此序列中数据的字符串表示形式。
和 String 类含义类似的方法

public static void main(String[ ] args) {

        /**StringBuilder*/
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 7; i++) {
            sb.append((char) ('a' + i));//追加单个字符
        }
        System.out.println(sb.toString());//转换成 String 输出
        sb.append(", I like learning");//追加字符串
        System.out.println(sb.toString());
        /**StringBuffer,下面的方法同样适用 StringBuilder*/
        StringBuffer sb2 = new StringBuffer("hello");
        sb2.insert(0, "好").insert(0, "你");//插入字符串
        System.out.println(sb2);
        sb2.delete(0, 2);//删除子字符串
        System.out.println(sb2);
        sb2.deleteCharAt(0).deleteCharAt(0);//删除某个字符
        System.out.println(sb2.charAt(0));//获取某个字符
        System.out.println(sb2.reverse());//字符串逆序

  
}

在这里插入图片描述

总结

String经过初始化后,就不会改变其内容了,对String字符串的操作实际上是对其副本(原始拷贝)的操作,原来的字符串不会改变。如:String s = "a"; s = s + "b";实际上是原来的“a”字符串已经丢弃了,重新产生一个字符串s + “b”(“ab”)。如果多次执行这些改变,会导致大量副本字符串对象存留在内存中,降低效率,如果这种操作放在循环中,会极大的影响程序的时间和空间性能。甚至会造成服务器的浪费。而StringBuilder和StringBuffer类是对原始字符串本身操作的,可以对字符串进行修改而不产生副本或者减少生成副本。

枚举

JDK1.5引入了枚举类型,枚举类型的定义包括枚举声明和枚举体。
所有的枚举类型隐性地继承自 java.lang.Enum。枚举实质上还是类!而每个被枚举的成员实质就是一个枚举类型的实例,他们默认都是 public static final 修饰的。可以直接通过枚举类型名使用它们

public enum Season {
    SPRING,
    SUMMER,
    AUTUMN,
    WINTER
}

需要定义一组常量时,可以使用枚举类型。
尽量不要使用枚举的高级特性,事实上高级特性都可以使用普通类来实现,没有必要引入枚举,增加程序的复杂性!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值