Day43 JDK1.8新特性
1.接口的默认方法与静态方法
从JDK1.8开始,接口中可以有默认方法,既default修饰的方法,此方法可以让接口的实现类所调用,而接
口中的静态方法直接用接口名调用即可
public class Test1 {
@Test
public void test01() {
MyClass myClass = new MyClass();
myClass.defaultMethod();
I1.staticMethod();
}
}
interface I1{
default void defaultMethod(){
System.out.println("接口中的默认方法");
}
public static void staticMethod(){
System.out.println("接口中的静态方法");
}
}
class MyClass implements I1{}
接口默认方法的”类优先”原则:
如果一个接口中定义了一个默认方法,而接口实现类的父类定义了一个同名的方法时,选择父类中的方法
接口冲突:如果一个父接口提供一个默认方法,而另一个接口也提供了一个具有相同名称和参数列表的方法(不管方法是否是默认方法),那么必须覆盖该方法来解决冲突
public class Test01 {
public static void main(String[] args) {
B b = new B();
b.method();
}
}
interface I1{
default void method(){
System.out.println("I1接口中的method方法");
}
}
class A{
public void method(){
System.out.println("A类中的method方法");
}
}
class B extends A implements I1{}
public class Test01 {
public static void main(String[] args) {
}
}
interface I1{
default void method(){}
}
interface I2 extends I1{
public void method();
}
class A implements I2{
@Override
public void method() {
}
}
2.日期组件
JDK1.8提供的新日期类都是不可变的,既不管怎么样的改变,都会产生一个新的实例,他们都是线程安全的
日期组件遵循与IOS-8601世界时间标准
2.1 组件简介
包路径 | 类名 | 描述 |
---|---|---|
java.time | 针对日期和时间操作的包 | |
LocalDate | 用于表示日期的类 | |
LocalTime | 用于表示时间的类 | |
LocalDateTime | 用于表示日期时间的类 | |
Instant | 时间戳类(1970.1.1 0:0:0 到现在的毫秒数) | |
Period | 两个日期间隔类 | |
Duration | 两个时间间隔类 | |
java.time.chrono | 针对日期时间特殊格式操作的包 | |
JapaneseChronology | 日本帝国历法系统类 | |
ThaiBuddhistChronology | 泰国佛教日历系统类 | |
java.time.format | 针对时间日期时间格式化操作的包 | |
DateTimeFormatter | 格式化日期时间类 | |
java.time.temporal | 针对时间矫正操作的包 | |
java.time.zone | 针对时区操作的包 |
2.2 日期时间类、时间戳、间隔类
public class Test1 {
@Test
public void test01() {
//LocalDate LocalTime LocalDateTime
//这三个日期类的使用大致一样
//获取当前日期时间对象
LocalDateTime ldt1 = LocalDateTime.now();
System.out.println(ldt1);
//获取指定日期时间对象
LocalDateTime ldt2 = LocalDateTime.of(2020, 1, 23, 8, 30, 10, 10);
System.out.println(ldt2);
//获取ldt1推后的时间日期对象
LocalDateTime ldt3 = ldt1.plusYears(2);
System.out.println(ldt3);
//获取ldt1提前的时间日期对象
LocalDateTime ldt4 = ldt3.minusMonths(2);
System.out.println(ldt4.getYear());
System.out.println(ldt4.getMonthValue());
System.out.println(ldt4.getDayOfMonth());
System.out.println(ldt4.getHour());
System.out.println(ldt4.getMinute());
System.out.println(ldt4.getSecond());
}
@Test
public void test02() {
//使用时间戳(从1970年1月1日0:0:0到现在的毫秒值)
//默认创建UTC(世界标准时间)时区的时间戳对象
Instant now1 = Instant.now();
System.out.println(now1);
//获取偏移8小时的偏移日期时间对象
OffsetDateTime odt = now1.atOffset(ZoneOffset.ofHours(8));
System.out.println(odt);
//获取时间戳的毫秒值形式
System.out.println(now1.toEpochMilli());
//获取一个1970年1月1日0:0:0 往后退1秒的时间戳对象
Instant now2 = Instant.ofEpochSecond(1);
System.out.println(now2);
}
@Test
public void test03() throws InterruptedException {
//Duration:时间间隔类
Instant now1 = Instant.now();
Thread.sleep(1000);
Instant now2 = Instant.now();
//获取时间间隔类对象
Duration duration1 = Duration.between(now1, now2);
System.out.println(duration1.toMillis());
System.out.println("-----------------------------");
LocalTime lt1 = LocalTime.now();
Thread.sleep(1000);
LocalTime lt2 = LocalTime.now();
//获取时间间隔类对象
Duration duration2 = Duration.between(lt1, lt2);
System.out.println(duration2.toMillis());
}
@Test
public void test04() throws InterruptedException {
//Period:日期间隔类
LocalDate ld1 = LocalDate.now();
Thread.sleep(1000);
LocalDate ld2 = LocalDate.of(2020, 12, 31);
Period period = Period.between(ld1, ld2);
System.out.println(period.getYears());
System.out.println(period.getMonths());
System.out.println(period.getDays());
}
}
2.3 日期时间格式化类-DateTimeFormatter
public class Test1 {
@Test
public void test01() {
//格式化日期时间类
LocalDateTime ldt1 = LocalDateTime.now();
//获取本地标准的日期时间格式化对象
DateTimeFormatter dtf1 = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
String strDateTime1 = ldt1.format(dtf1);//格式化时间日期
System.out.println(strDateTime1);
//自定义日期时间格式化对象
DateTimeFormatter dtf2 = DateTimeFormatter.
ofPattern("yyyy年MM月dd日 HH:mm:ss");
String strDateTime2 = ldt1.format(dtf2);//格式化时间日期
System.out.println(strDateTime2);
//将指定格式的字符串解析成LocalDateTime对象
LocalDateTime parse = LocalDateTime.parse("2020年03月12日 11:04:14", dtf2);
System.out.println(parse);
}
}
2.4 时间矫正器类-TemporalAdjuster
public class Test1 {
@Test
public void test01() {
//时间矫正器
LocalDateTime ldt1 = LocalDateTime.now();
//设置指定月份
LocalDateTime ldt2 = ldt1.withMonth(10);
System.out.println(ldt2);
//设置下一个周末
LocalDateTime ldt3 = ldt1.with(TemporalAdjusters.next(DayOfWeek.SUNDAY));
System.out.println(ldt3);
//自定义时间矫正器:设置下一个工作
LocalDateTime ldt4 = ldt1.with((temporal)->{
LocalDateTime ldt = (LocalDateTime) temporal;
DayOfWeek week = ldt.getDayOfWeek();
if(week.equals(DayOfWeek.FRIDAY)){//周五
return ldt.plusDays(3);
}else if(week.equals(DayOfWeek.SATURDAY)){//周六
return ldt.plusDays(2);
}else{
return ldt.plusDays(1);
}
});
System.out.println(ldt4);
}
}
2.5 时区类
public class Test1 {
@Test
public void test01() {
//时区类
//获取所有时区字符串
Set<String> set = ZoneId.getAvailableZoneIds();
for (String str : set) {
System.out.println(str);
}
//获取指定时区的日期时间对象
LocalDateTime ldt1 = LocalDateTime.now(ZoneId.of("Asia/Tokyo"));
System.out.println(ldt1);
//获取指定时区的日期时间对象 + 偏移量
LocalDateTime ldt2 = LocalDateTime.now(ZoneId.of("Asia/Tokyo"));
ZonedDateTime zonedDateTime = ldt2.atZone(ZoneId.of("Asia/Tokyo"));
System.out.println(zonedDateTime);
}
}
2.6 重复注解及类型注解
jdk1.8开始可以重复注解
ps:一个类可有多个同样的注解
@Author(name="何老师")
@Author(name="波多老师")
public class Test01 {
public static void main(String[] args) throws NoSuchMethodException, SecurityException {
Class<?> clazz = Test01.class;
//获取类上的注解
Author[] as = clazz.getDeclaredAnnotationsByType(Author.class);
for (Author author : as) {
System.out.println(author.name());
}
//获取参数上的注解
Method method = clazz.getMethod("method", String.class);
Parameter[] parameters = method.getParameters();
for (Parameter parameter : parameters) {
Author annotation = parameter.getAnnotation(Author.class);
System.out.println(annotation.name());
}
}
public void method(@Author(name="何老师") String str){}
}
作者注解
@Repeatable(Authors.class)//使用重复注解,就必须加上该注解
@Target({ElementType.TYPE,ElementType.PARAMETER})//TYPE_PARAMETER-类型注解:作用在参数
@Retention(RetentionPolicy.RUNTIME)
public @interface Author {
String name();
}
作者注解的容器
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Authors {
Author[] value();
}
总结
1.接口的类优先原则 和 接口冲突
2.日期时间组件
3.重复注解
经验:JDK1.8新特性
Lambda - 重要
函数式接口 - 重要
方法的引用 - 重要
Stream - 重要
日期时间组件(LocalDate、LocalTime、LocalDateTime、Instant、DateTimeFormatter) – 重要