1.String
- 真正存放值的是String类中的private final byte[] value;
- value地址不可更改,但是因为是一个数组,所以其内部值其实是可以更改的,但是因为String并没有提供让其数组内部元素更改的方法,所以String整体仍然是不可变的 :::danger 字符串常量相加,看池,变量相加,是在堆里面 ::: ```java //会被编译器在底层优化为String str=”ab”; 实际上只创建了一个对象 String str=”a”+”b”;
String a = “a”; String b = “b”; //ab直接指向常量池,c是通过创建一个stringbuilder对象,随后通过append将a,b添加进去,再new了 //一个String返回,所以c是指向堆的,堆中value数组指向常量池 String c = a + b;
<a name="JSZFP"></a>## 1.String不同的创建方式区别<a name="UYOTP"></a># 2.StringBuffer1. 继承至**AbstractStringBuilder**,本身**不能被继承**,数据存放在AbstractStringBuilder的byte[] value中,不再是final类型,值存放在堆中,所以可变,1. StringBuffer的默认长度为**16**1. 当字符串对象 String str=null时,使用append(str)追加对象不会发生错误,但是new StringBuffer(str)则会空指针异常1. **多线程安全**```javaString d=Null;StringBuffer aa = new StringBuffer();aa.append(d); //通过System.out.println(aa.length());new StringBuffer(str) //报空指针异常
以上代码不会报错,且长度为4,因为在源码中,当传入的字符串对象为空时,生成一个值为“null”的数组
private AbstractStringBuilder appendNull() {ensureCapacityInternal(count + 4);int count = this.count;byte[] val = this.value;if (isLatin1()) {val[count++] = 'n';val[count++] = 'u';val[count++] = 'l';val[count++] = 'l';} else {count = StringUTF16.putCharsAt(val, count, 'n', 'u', 'l', 'l');}this.count = count;return this;}
3.StringBuilder
- 线程不安全
- 继承至AbstractStringBuilder,本身不能被继承,数据存放在AbstractStringBuilder的byte[] value中,不再是final类型,值存放在堆中,所以可变,(与StringBuffer相同)
-
4.大数
- BigInteger和BigDecimal,两者都是在底层以字符串的方式存储数据,所以长度与精度可以无限
- BigInteger是大整形数,BigDecimal是高精度浮点数
- BigInteger和BigDecimal都需要一个同类型的变量作为另外的参与运算的条件,加减乘除等也必须调用相对应的方法,而不是直接使用计算符号
BigDecimal的除法当除不尽或者为0时,可能抛出异常,可以用重载的除法解决
BigDecimal bigDecimal = new BigDecimal("122.12324546766543211");//参与运算的条件也必须是相同的类型BigDecimal bigDecimal1 = new BigDecimal("1.1");//重载的除法,第二个参数表示保留的精度为被除数的精度,就不会有除不尽的问题了BigDecimal divide = bigDecimal.divide(bigDecimal1, RoundingMode.CEILING);System.out.println(divide);
5.日期
1.第一代日期类
Date,精确到毫秒
SimpleDateFormat,格式和解析日期的类,创建对象时传入指定的格式字符串,就可将date转为指定的格式了。
2.第二代日期类
Calendar日历类,抽象类
使用Calendar.getInstance()获取实例,通过实例对象.get()等方式,获得各个属性
Calendar instance = Calendar.getInstance();System.out.println(instance.get(Calendar.MONTH));
3.第三代日期类
前两代日期类都存在问题:
日期应该是不可变的
- Date年份是从1900开始,月份从0开始
- 格式化只对Date有用,Canlendar不行
- 线程不安全,且不能处理闰秒(每隔2天,多出1秒)
LocalDate、LocalTime、LocalDateTime
时间日期类
- 可以格式化日期
可以对日期和时间进行运算//使用静态方法生成当前时间LocalDateTime now = LocalDateTime.now();//获取时间和日期值System.out.println(now.getYear());System.out.println(now.getMonthValue());System.out.println(now.getSecond());//格式化DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH : mm: ss");//对localdatetime格式化String format = formatter.format(now);//格式化后的日期System.out.println(format);
//增加天数LocalDateTime localDateTime = now.plusDays(2);//减少天数LocalDateTime localDateTime1 = now.minusDays(1);
Instant时间戳
类似于Date类 ,提供和Date相互转换的方式//生成instant对象Instant now = Instant.now();//instant转dateDate from = Date.from(now);System.out.println(from);//date转instantInstant instant = from.toInstant();System.out.println(instant);
