Object类
类层次结构的根。所有类都默认继承Object类。
public String toString()
返回对象的字符串表达形式。
- 直接打印对我们意义不大,一般是重写toString()以便返回对象的内容。
- 重写方法:①右键-generate-toString(),②写toS自动生成。
public boolean equals(Object o)
指示某个其他对象是否“等于”此对象。
- 默认是判断两个对象的地址是否相等。但在开发中,这个功能用“==”也能实现。
- 在开发中也是为了让子类重写,比较两个对象的内容一样。
- 重写方法:写eq自动生成,反复回车即可。
- 原理:比较者是this,被比较者是o。①首先判断两个对象是否地址一样,一样直接返回true,②判断o是null直接返回false,或者比较者和被比较者的类型不同,返回false,③o不是null,且o一定是相同类型的对象,就开始比较内容。将o强制转换为比较者类型,然后比较。
public String clone()
创建并返回对象的副本。
- 由protected修饰,也就是只能在当前包(java.lang)、Object子类中才能访问。
- 要使用clone()方法,必须要在子类中重写该方法。再通过它中转调用父类的克隆方法。
- 重写方法:在子类中输入“clon”自动创建。这里是super去调用父类Object。克隆出来返回Object对象。
- 注意:不是所有类都能克隆。克隆的话还要让子类实现一个接口(implements Clonable)。这个接口里面啥都没,称为标记接口(规则)。实例调用clone()的时候会报错,暂时可以“Alt+Enter”选择第一个,此时自动在main方法后面加上了“throws CloneNotSupportedException”。
Java中有两种克隆:浅克隆(上述)、深克隆。
- 浅克隆:拷贝出的新对象和原对象中的数据一模一样(引用类型拷贝的只是地址,所以指向的是一样的内容)。
- 深克隆:
- 对象中的基本类型的数据直接拷贝。
- 对象中的字符串数据拷贝地址。
- 对象中包含的其他对象,不拷贝地址,创建新对象。
Objects类
一个工具类,提供了很多操作对象的静态方法。
equals(Object a, Object b)
先做非空判断,再比较两个对象。
- 为什么官方选择Objects.euqals(s1,s2)而不是s1.equals(s2)呢?避免s1为null时的报错。
isNull(Object obj)
判断对象是否为null,为null返回true,反之。
- 其实和“对象==null”效果一样,看起来高级。
nonNull(Object obj)
判断对象是否不为null,不为null返回true,反之。
- 其实和“对象!=null”效果一样,看起来高级。
包装类
为什么要有?
- 因为基本类型数据不是对象。为了实现“万物皆对象”,所以使用包装类用来把基本类型的数据包装成对象。
基本数据类型 | 对应的包装类(引用数据类型) |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
char | Character |
float | Float |
double | Double |
boolean | Boolean |
如何包装的?
- valueOf(int i):例如,Integer a1 = Integer.valueOf(12);
Java中为了方便把基本类型的数据转换成对象,提供了两种方案:
- 自动装箱机制(自动把基本类型数据转换为对象)。例如,Integer a2 = 12;
- 自动拆箱(自动把包装类型对象转换为基本数据类型)。例如,int a3 = a2;
为什么重要?
- 泛型和集合不支持基本数据类型,只支持引用数据类型。例如,Arraylist
对而Arraylist 错误。
包装类有什么特殊的方法?
把基本类型的数据转换为字符串类型。例如,Integer a = 23; String rs1 = Integer.toString(a);和String rs2 = a.toString();的效果一样。(也可以用String rs3 = a + “”,所以这个方法应用不多。)
把字符串类型的数值转换成数值本身对应的数据类型。例如,String ageStr = “29”; int ageI = Integer.parseInt(ageStr);//String scoreStr = “99.5”; double score = Double.parseDouble(scoreStr );。这样其实是麻烦的,直接使用valueOf,例如,int ageI = Integer.valueOf(ageStr);只需要记住一个函数即可。
注意:转换前的数值一定要是对应类型,否则报错。
StringBuilder类
可变字符串对象。相当于一个容器,里面装的字符串是可以变的。用来操作字符串。
为什么要有(好处)?
- 比String更适合做字符串修改的操作,效率更高,代码更简洁。
构造器
- 无参构造器。public StringBuilder()。创建一个空白的可变字符串对象,不包含任何内容。
- 有参构造器。public StringBuilder(String str)。创建一个指定字符串内容的可变字符串对象。
常用方法
public StringBuilder append(任意类型)。添加数据并返回StringBuilder 对象本身。
拼接内容。支持链式编程,例如,s.append(666).append(“hello”);。
public StringBuilder reverse()。将对象的内容反转。
反转操作。
public int length()。返回对象内容长度。
public String toString()。把StringBuilder对象又转换成String类型。
为什么操作字符串建议使用StringBuilder,而不用原来学过的String?
- 效率高。
- 对于字符串相关操作,如果频繁拼接、修改等,建议用StringBuilder,效率高。如果字符串较少,或者不需要操作,以及定义字符串变量,建议用String。
案例
设计一个方法,用于返回任意整型数组的内容,要求返回的数组内容格式如下:[11, 22, 33]。(需要用if判断是否到最后一个元素以确定数字后面的符号。)
StringBuffer类
与StringBuilder用法一样。但是StringBuilder是线程不安全的,StringBuffer是线程安全的。(就是很多人进入系统来用StringBuffer编程时不会出bug。)
StringJoiner类
解决的问题:StringBuiler虽然速度上去了,但是代码层面很麻烦(如前例,还要if来判断)。怎么高效、方便地拼接?
- JDK8开始才有,和StringBuiler类似。
- 好处:提高字符串的操作效率,在某些场景下代码更加简洁。
构造器
- public StringJoiner(间隔符号)。创建StringJoiner对象,指定拼接时的间隔符号。
- public StringJoiner(间隔符号,开始符号,结束符号)。创建StringJoiner对象,指定拼接时的间隔符号、开始符号、结束符号。
常用方法
- public StringJoiner add(添加的内容)。添加数据,返回对象本身。
- public int length()。返回长度(字符串出现的个数)。
- public String toString()。返回一个字符串(该字符串就是拼接之后的结果)。
因此,可以将输出数组格式的代码简化。
Math类
数学,是一个工具类。提供对数据进行操作的静态方法。
常见方法
- public static int abs(int a)、public static double abs(double a)。获取参数绝对值。
- public static double ceil(double a)。向上取整。
- public static double floor(double a)。向下取整。
- public static int round(float a)。四舍五入。
- public static int max(int a, int b)。获取两个int值中的较大值。
- public static double pow(double a, double b)。返回a的b次幂的值。
- public static double random()。返回值为double的随机值,范围[0.0, 1.0)。
System类(了解)
程序所在的系统。工具类。
常见方法
- public static void exit(int status)。终止当前运行的Java虚拟机。
- 该参数用作状态代码;按照惯例,非零状态代码表示异常终止。
- System.exit(0); //人为地终止虚拟机(不要使用)。
- public static long currentTimeMills()。返回当前系统的时间毫秒值形式。从1970-1-1 0:0:0开始(小知识:为啥是这个时间开始?C语言的生日。)到此刻的毫秒值。
- 通常用作代码的性能分析。
- 想转换成秒数:time/1000.0。
Runtime类(了解)
程序所在的运行环境。是单例类。通过调用getRuntime()方法来得到对象。
常见方法
- public static Runtime getRuntime()。返回与当前Java应用程序关联的运行时对象。
- public void exit(int status)。终止当前运行的虚拟机。该参数用作状态代码。按照管理,非零状态码表示异常终止。(其实System类里面的exit方法就是调用的这里。)
- public int availableProcessors()。返回Java虚拟机可用的处理器数。
- public long totalMemory()。返回Java虚拟机中的内存总量。返回的是字节数,想看多少K,除以1024.0,多少M,再除以1024.0。
- public long freeMemory()。返回Java虚拟机中的可用内存。返回的是字节数。
- public Process exec(String command)。启动某个程序,并返回代表该程序的对象。
- 用法:拷贝exe程序的路径(右键-属性-安全-对象名称),作为参数传给exec。此时报异常,用“Alt+Enter”选第一个,自动抛出异常(在类定义处增加throw IOException)。程序就会帮我们打开指定的exe程序。
- 多说一点,可以直接传程序名,前提是系统环境变量里面配置程序的路径。
- 用Process类定义一个变量来接返回的程序对象,接到之后用destroy()方法关闭程序。
BigDecimal类
解决浮点型运算时,出现结果失真的问题(如,0.1+0.2的结果不是0.3)。
构造器
public BigDecimal(String val)。把String转成BigDecimal。是按照对应位置运算的。
常用方法
- public static BigDecimal valueOf(double val)。转换一个double成BigDecimal。
- public BigDecimal add(BigDecimal b)。加法。
- public BigDecimal substract(BigDecimal b)。减法。
- public BigDecimal multiply(BigDecimal b)。乘法。
- public BigDecimal devide(BigDecimal b)。除法。
- public BigDecimal devide(另一个BigDecimal对象,精确几位,舍入模式)。除法,可以控制精确到小数几位。
- public BigDecimal doubleValue()。将BigDecimal转换为double。
- 推荐方式:使用时先toString()变成字符串对象,封装成BogDecimal对象,再运算。//或者调用valueOf进行简化。即BigDecimal a1 = new BigDecimal (Double.toString(a))简化为BigDecimal a1 = BigDecimal.valueOf(a)。
- 做除法运算时,如果不能正好表达,就会报无法精确表达结果的错,所以就要用第二种除法方法。这只是解决精度问题的手段,最后还要转换为double类型的数据。
- 注意:一般不用构造方法BigDecimal(double)的方式把double值转化为BigDecimal对象,因为存在精度损失风险,可能导致业务逻辑异常。有限推荐入参为String的构造方法,或者使用BigDecimal的valueOf方法,此方法内部执行了Double的toString,而Double的toString按double的实际能表达的精度对尾数进行了截断。
日期和时间(JDK8之前)
Date类
系统的日期和时间。(可以直接打印出来。)
构造器
- public Date()。 创建一个Date对象,代表的是系统当前此刻日期时间。
- public Date(long time)。 把时间毫秒值转换成Date日期对象。
常用方法
- public long getTime()。返回从1970年1月1日 00:00:00走到此刻的总的毫秒数。
- public void setTime(long time)。设置日期对象的时间为当前时间毫秒值对应的时间。
SimpleDateFormat类
简单日期格式化,可以用来把日期对象、时间毫秒值格式化成我们想要的形式。
- 允许格式化(日期-文本)、解析(文本-日期)和规范化。
- 时间格式: xxxx-xx-xx xx:xx:xx。
- 可以将Date或者时间毫秒值转化为上述格式。
构造器
public SimpleDateFormat(String pattern)。创建简单日期格式化对象,并封装时间的格式。可以自己看文档组装成想要的格式,例如,“yyyy-MM-dd HH:mm:ss EEE a”。
常用方法
public final String format(Date date)。将日期格式化成日期/时间字符串。
public final String format(Object time)。将时间毫秒值式化成日期/时间字符串。
即,这个函数既可以扔进来一个SimpleDateFormat类,也可以直接扔进来系统时间毫秒值。
public Date parse(String source)。把字符串时间解析成日期对象。
使用:①创建SimpleDateFormat对象,指定的时间格式必须与被解析的时间格式一模一样;②把字符串扔到SimpleDateFormat对象中用parse()方法解析。此时还是要用“Alt+Enter”把异常抛出去。
常见符号
y年,M月,d日,H时,m分,s秒,EEE星期几,a上午/下午。
Calendar类
系统此刻时间对应的日历。
- 通过它可以单独获取、修改时间中的年、月、日、时、分、秒等。(注意月是从0开始的。)
- 是一个抽象类。要用的话需要找它的子类(实现类)。
- calendar是可变对象,一旦修改后其对象本身表示的时间将产生变化。
为什么要学习?
- 从一个案例说起,需求是将2023年09月10日增加一个月。常用做法是:1、记住字符串,2、解析成Date日期对象,3、通过日期对象获取毫秒值,4、增加一个月的毫秒值,5、格式化得到结果。
常用方法
- public static Calendar getInstance()。获取当前日历对象。
- public int get(int field)。获取日历中的某个信息。例如,.get(Calendar .YEAR);
- public final Date getTime()。获取日期对象。
- public long getTimeInMillis()。获取时间毫秒值。
- public void set(int field,int value)。修改日历的某个信息。
- public void add(int field,int amount)。为某个信息增加/减少指定的值。
JDK8开始新增的日期、时间
为什么要学?(Java开发者的bug。)
- JDK8之前传统的时间API:1、设计不合理,使用不方便,很多都被淘汰了。2、都是可变对象,修改后会丢失最开始的时间信息。3、线程不安全。4、只能精确到毫秒。
- JDK8开始之后新增的时间API:1、设计更合理,功能丰富,使用更方便。2、都是不可变对象,修改后会返回新的时间对象,不会丢失最开始的时间。3、线程安全。4、能精确到毫秒、纳秒。
代替Calendar类
- LocalDate:本地日期(年、月、日、星期)。这是一个不可变对象。
- public static Xxxx now()。获取系统当前时间对应的该对象。
- public static Xxxx of(…)。获取指定时间的对象。例如,getYear()、getMonthValue()、getDayOfMonth()、getDayOfYear()、getDayOfWeek()等。
- withYear、withMonth、withDayOfMonth、withDayOfYear。直接修改某个信息,返回新日期对象。
- plusYears、plusMonths、plusDays、plusWeeks。把某个信息加多少,返回新日期对象。
- minusYears、minusMonths、minusDays,minusWeeks。把某个信息减多少,返回新日期对象。
- equals、isBefore、isAfter:判断两个日期对象,是否相等,在前还是在后 。LocalDate.of:获取指定日期的LocalDate对象。public static LocalDate of(int year, int month, int dayOfMonth)。
- LocalTime:本地时间(时、分、秒、纳秒)。这是一个不可变对象。
- public int getHour()、public int getMinute()、public int getSecond()、public int getNano()。获取小时、秒、纳秒。
- withHour、withMinute、withSecond、withNano。修改时间,返回新时间对象。
- plusHours、plusMinutes、plusSeconds、plusNanos。把某个信息加多少,返回新时间对象。
- minusHours、minusMinutes、minusSeconds、minusNanos。把某个信息减多少,返回新时间对象。
- equals、isBefore、isAfter:判断2个时间对象,是否相等,在前还是在后。
- LocalDateTime:本地日期、时间(年、月、日、星期、时、分、秒、纳秒)。这是一个不可变对象。
- 方法综合前两个。
- 特殊的:可以把LocalDateTime转换成LocalDate和LocalTime,使用toLocalDate()和toLocalTime()方法。而用LocalDateTime.of(LocalDate ld, LocalTime lt)可以再把它们合起来。
- ZoneId:时区Id。
- 常识:世界标准时间(UTC)是0时区,中国标准时间是世界标准时间(UTC) + 8小时。
- 表达方式:洲名/城市名,国家名/城市名。
- 常见方法:
- public static Set
getAvailableZoneIds()。获取Java中支持的所有时区。(如果不记得时区Id怎么写可以调用这个看一下。) - public static ZoneId systemDefault()。获取系统默认时区。然后可以用getId()方法/直接打印获取当前系统的默认时区。
- public static ZoneId of(String zoneId)。将指定时区Id封装成ZoneId对象。结合下面的ZonedDateTime使用。
- public static Set
- ZonedDateTime:带时区的时间。
- 常见方法:
- public static ZonedDateTime now() 。获取当前时区的ZonedDateTime对象。
- public static ZonedDateTime now(ZoneId zone) 。获取指定时区的ZonedDateTime对象。例如传入Clock.systemUTC()参数获取世界标准时间。
- getYear、getMonthValue、getDayOfMonth、getDayOfYeargetDayOfWeek、getHour、getMinute、getSecond、getNano。获取年月日、时分秒、纳秒等。
- public ZonedDateTime withXxx(时间) 。修改时间系列的方法。
- public ZonedDateTime minusXxx(时间) 。减少时间系列的方法。
- public ZonedDateTime plusXxx(时间)。增加时间系列的方法。
- 常见方法:
代替Date类
- Instant:时间戳/时间线。是一个不可变对象。
- 通过获取Instant的对象可以拿到此刻的时间,该时间由两部分组成:从1970-01-01 00:00:00 开始走到此刻的总秒数 + 不够1秒的纳秒数。
- 可以用来记录代码的执行时间,或用于记录用户操作某个事件的时间点。传统的Date类,只能精确到毫秒,并且是可变对象;新增的Instant类,可以精确到纳秒,并且是不可变对象,推荐用Instant代替Date。
- 常用方法:
- public static Instant now()。获取当前时间的Instant对象(标准时间)。
- public long getEpochSecond()。获取从1970-01-01T00:00:00开始记录的秒数。
- public int getNano()。从时间线开始,获取从第二个开始的纳秒数 。
- plusMillis plusSeconds plusNanos。增加时间系列的方法。
- minusMillis minusSeconds minusNanos。减少时间系列的方法。
- equals、isBefore、isAfter。判断时间系列的方法。
代替SimpleDateFormat类
- DateTimeFormatter:用于时间的格式化和解析。(线程安全。)
- 常用方法:
- public static DateTimeFormatter ofPattern(时间格式)。获取格式化器对象。
- public String format(时间对象)。格式化时间。
- public String format(DateTimeFormatter formatter)。格式化时间。
- public static LocalDateTime parse(CharSequence text, DateTimeFormatter formatter)。解析时间。
- 正向格式化:formatter.format(now),反向格式化:now.format(formatter)。得到的结果是一样的。
- LocalDateTime提供的格式化、解析时间的方法:
- public String format(DateTimeFormatter formatter)。格式化时间。
- public static LocalDateTime parse(CharSequence text, DateTimeFormatter formatter)。解析时间。
其他补充
- Period:时间间隔(年,月,日)。用于计算两个 LocalDate对象相差的年数、月数、天。注意先写较前的时间,再写较后的时间。
- public static Period between(LocalDate start, LocalDate end)。传入2个日期对象,得到Period对象。
- public int getYears()。计算隔几年,并返回。
- public int getMonths()。计算隔几个月,年返回。
- public int getDays()。计算隔多少天,并返回。
- Duration:时间间隔(时、分、秒,纳秒)。计算两个时间对象相差的天数、小时数、分数、秒数、纳秒数;支持LocalTime、LocalDateTime、Instant等时间。
- public static Duration between(开始时间对象1,截止时间对象2)。传入2个时间对象,得到Duration对象。
- public long toDays()。计算隔多少天,并返回。
- public long toHours()。计算隔多少小时,并返回。
- public long toMinutes()。计算隔多少分,并返回。
- public long toSeconds()。计算隔多少秒,并返回。
- public long toMillis()。计算隔多少毫秒,并返回。
- public long toNanos()。计算隔多少纳秒,并返回。