String的创建方式

3 篇文章 0 订阅

String概述

String类型是java的一个最基本的对象,他底层是用char[]实现,是一个不可继承类,即final类。
String是我们平时使用最多的,所以我们要深入理解String类他的实现和底层。
前置:value是字符数组,而且是一个常量不可变,。
hash 默认是0

构造函数

无参构造

String类型的无参构造,他是将空字符串给了char[]

public String() {
	this.value = "".value;
}

值得注意的是String new与不new的区别是什么??
我们熟知JVM有堆,栈,方法区,方法区里存放这常量池。
当我们使用String类型直接赋值的时候,首先会去常量池查看是否已经有这个常量,如果有就不需要创建了直接引用就行了,没有就创建在引用。但是如果使用了new的方式来创建这个String,那么中间就会多一步过程,当我们在new的时候,它首先会查看常量池是否有这个常量,如果有的话,那么直接获取这个地址,但是因为他new了,所以会在堆中创建一个String的实例,然后这个实例引用了常量池的地址,而栈中的变量就引用了堆中实例的地址,也就是说new的话,会占用两块内存空间。所以一般推荐不要使用new的方式来创建。

构造方法参数为String类型

这种方法就是一个赋值的过程

public String(String original) {
    this.value = original.value;
    this.hash = original.hash;
}

一般情况下,除非需要显式副本,那么不需要使用这个构造函数,因为字符串是不可变的(官方)

char[]参数的构造函数

这个构造函数就是为了把字符数组转换为一个String类型的字符串。

public String(char value[]) {
    this.value = Arrays.copyOf(value, value.length);
}

他调用了Arrays的copyOf方法,这个方法底层调用了System的arraycopy方法,是一个native方法,这是一个本地方法,也就是说他是通过JVM来实现的,效率相比其他转换方法要高。

char[],int,int 参数构造方法

两个int的值分别表示偏移量和数量,最底层也是调用了System的arraycopy方法。就不多讲了

int[],int,int 参数构造方法

int数组怎么转换为字符串类型?基础好的同学会清楚UNICODE ,他会将int类型转换为UNICODE所代表的相应字符,在早起UNICODE用char是能够全部表示的,但是在UNICODE4.0之后规定的支持字符远超与char所能支持,所以使用了int类型来进行代替。

	public String(int[] codePoints, int offset, int count) {
        if (offset < 0) {
            throw new StringIndexOutOfBoundsException(offset);
        }
        if (count <= 0) {
            if (count < 0) {
                throw new StringIndexOutOfBoundsException(count);
            }
            if (offset <= codePoints.length) {
                this.value = "".value;
                return;
            }
        }
        // 偏移量判断
        if (offset > codePoints.length - count) {
            throw new StringIndexOutOfBoundsException(offset + count);
        }

        final int end = offset + count;

        // 1.计算char []的精确大小
        int n = count;
        for (int i = offset; i < end; i++) {
            int c = codePoints[i];
            // 判断是否能够被char表示
            if (Character.isBmpCodePoint(c))
                continue;
                // 校验是否是UNICODE代码点 如果能长度+1 否则抛出异常
            else if (Character.isValidCodePoint(c))
                n++;
            else throw new IllegalArgumentException(Integer.toString(c));
        }

        // 2.填充和分配char []
        final char[] v = new char[n];

        for (int i = offset, j = 0; i < end; i++, j++) {
            int c = codePoints[i];
            if (Character.isBmpCodePoint(c))
                v[j] = (char)c;
            else
            // 转换成char能表示的字符
                Character.toSurrogates(c, v, j++);
        }

        this.value = v;
    }

byte[],int,int,String 构造函数

参数意义:字节数组,偏移量,数量,字符集名称(对应java.nio.charset.Charset);

	public String(byte bytes[], int offset, int length, String charsetName)
            throws UnsupportedEncodingException {
        if (charsetName == null)
            throw new NullPointerException("charsetName");
            // 校验是否合理
        checkBounds(bytes, offset, length);
        this.value = StringCoding.decode(charsetName, bytes, offset, length);
    }

字符集默认使用的是什么?ISO-8859-1.
注意:字符集需要是java.nio.charset.Charset包含的,如果不存在就会抛出UnsupportedEncodingException。

static char[] decode(String charsetName, byte[] ba, int off, int len)
        throws UnsupportedEncodingException
    {
        StringDecoder sd = deref(decoder);
        String csn = (charsetName == null) ? "ISO-8859-1" : charsetName;

具体解码过程自行查看。
相似的构造函数
1.public String(byte bytes[], int offset, int length, Charset charset)
2.public String(byte bytes[], String charsetName)
3.public String(byte bytes[], Charset charset)
4.public String(byte bytes[], int offset, int length)
5.public String(byte bytes[])

StringBuffer 参数构造函数和StringBuilder 参数构造函数

这两种主要的区别就是加锁,线程安全的问题,也不多复述了.

	public String(StringBuffer buffer) {
        synchronized(buffer) {
            this.value = Arrays.copyOf(buffer.getValue(), buffer.length());
        }
    }
    public String(StringBuilder builder) {
        this.value = Arrays.copyOf(builder.getValue(), builder.length());
    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值