java数据类型
java分为两种数据类型:
1.基本数据类型
2.引用数据类型:如,类,接口,数组
基本数据类型:8种
- byte 1个字节
- short 2个字节
- int 4个字节
- long 8个字节
- float 4个字节
- double 8个字节
- char 2个字节
- boolean 1或4个字节,boolean类型较特殊,根据jvm虚拟机的处理方式不同大小可能不同,参考 添加链接描述
string字符串最大长度:编译器 65534 个字节(受限于CONSTANTUtf8类型的常量池数据项大小),运行期 Integer.MAX_VALUE 个字节(受限于string类中数组最大长度是int)
String为什么是不可变的
- 首先String类是final的,意味着String不可以被继承,内部的实现不能被修改
- 然后String类中用于保存数据的内部对象
private final char value[];
- 被设置成私有并且是final的
- 最后String类里的所有方法,sun工程师们都小心谨慎的避免修改到value数组中的元素,因为虽然value指向的地址被final关键字限制了不可变,但是内部的元素仍然可变,例如substring方法
public String substring(int beginIndex) {
if (beginIndex < 0) {
throw new StringIndexOutOfBoundsException(beginIndex);
}
int subLen = value.length - beginIndex;
if (subLen < 0) {
throw new StringIndexOutOfBoundsException(subLen);
}
return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);
}
该方法返回了新的String对象,而不是直接操作当前对象,其他方法类似
以上是String不可变的原因,但是为什么String不可变的好处是什么呢,一般认为有下列好处
- 安全
String被大量应用在各种方法出入参,hash结构做key,使用频次远远超出其他对象,如果是可变的则维护它不被莫名其妙修改掉的成本过于高了。
同时字符串是不可变的也就不可修改,在多线程环境中,字符串对象是线程安全的 - 性能
同样是因为String对象作为一个使用频次超高的引用类型,如果按照一般对象的模式来使用严重影响性能,所以工程师们为String类型设置了字符串常量池(此处不展开),不同字符串对象可以指向同样的字符串常量内存地址以此节省大量内存,但是这要基于字符串不可变的前提,否则指向同样地址的话修改一个其他的都跟着修改了。
Stringbuffer,StringBuilder的区别
- StringBuffer和StringBuilder都继承AbstractStringBuilder,具体的功能逻辑都在AbstractStringBuilder中实现
- StringBuilder的所有方法都直接使用了AbstractStringBuilder的实现即
public XX YY(){
return super.YY();
}
没有做什么改动
- StringBuffer的所有方法内容也跟StringBuilder一样,都使用的AbstractStringBuilder的实现,唯一的区别就是StringBuffer里的所有方法都加上了synchronized关键字,因此是线程安全的,但是性能比较差,但是StringBuffer使用了toStringCache,在调用toString方法时会将返回的结果保存在toStringCached对象中,如果没有做其它操作的前提下多次调用toString方法会直接读取这个cache