JDK8新特性之default、扩展注解、反射方法参数、hashmap性能提升

JDK8新特性之default、扩展注解、反射方法参数

  • 1 接口的 default 方法
  • 2 扩展注解支持
    • 2.1 增加FunctionalInterface注解
    • 2.2 对元注解的增强
    • 2.3 增加Repeatable 元注解
  • 3 增加反射方法参数
  • 4 对 HashMap 性能的提升
  • 5 新增时间的操作类

1 接口的 default 方法

  接口中方法默认使用public abstract修饰, 接口中字段默认使用public static final修饰.
  在 JDK8 中对接口进行增强, 可以定义 default 修饰的方法,也可以定义static修饰的方法
  default修饰的方法和static 修饰的方法主要用于接口功能增强时,如果接口已经定义完成,并且也有若干的实现类实现了该接口.根据业务需求,需要在接口中再增强其他的功能, 后面增强的功能可以使用default修饰. 之前定义好的实现类就不需要再进行修改

public interface MyInterface {
    //默认的抽象方法, 需要在实现类中重写 public abstract
    void m1();

    //字段默认 public stati cfinal修饰
    int XX = 121;

    //如果方法使用default 修饰, 表示该方法可以有默认的方法体,在实现类中可以重写,也可以不重写
    default void dm() {
        System.out.println("接口中使用default修饰的方法");
    }
    
    //静态方法
    static void sm(){
        System.out.println("接口中可以使用static定义静态方法");
    }
}
public class MyClass implements MyInterface {
    @Override
    public void m1() {
        System.out.println("在实现类中重写接口中的抽象方法");
    }
}
public class MyClass2 implements MyInterface {
    @Override
    public void m1() {
        System.out.println("在实现类中重写接口中的抽象方法");
    }

    @Override
    public void dm() {
        System.out.println("在实现类中重写接口中default修饰的方法");

    }
}
public class Test01 {
    public static void main(String[] args) {
        MyInterface mi = new MyClass();
        mi.dm();

        MyInterface mi2 = new MyClass2();
        mi2.dm();

        //调用接口的静态方法
        MyInterface.sm();
    }
}

2 扩展注解支持

2.1 增加FunctionalInterface注解

//注解声明接口为函数式接口
@FunctionalInterface
public interface MyFuncationInterFace {

    void m1();
    default void dm(){
        System.out.println("default修饰的方法有默认方法体");
    }
}
public class Test01 {
    public static void main(String[] args) {
        //接口赋值匿名内部类对象
        MyFuncationInterFace mi2 = new MyFuncationInterFace() {
            @Override
            public void m1() {
                System.out.println("在匿名内部类中重写接口的抽象方法");
            }
        };
        //执行匿名内部类对象的方法
        mi2.m1();

        //MyInteface2接口声明为了函数式接口,可以直接给接口引用赋值Labmda表达式
        mi2 = () -> System.out.println("给接口引用赋值 Lambda表达式");
        mi2.m1();
    }
}

2.2 对元注解的增强

  JDK8扩展了注解的使用范围,在ElementType枚举类型中增强了两 个枚举值:

  ElementType.PARAMETER,表示注解能写在类型变量的声明语句中
  ElementType.USE, 表示注解能写在使用类型的任何语句中(结合第三方插件可在编译期可以检测出运行时异常,如空指针、越界等)

2.3 增加Repeatable 元注解

  增加了 Repeatable 元注解.JDK8 前的版本中,同一个注解在同一个 位置只能使用一次,不能使用多次. 在JDK8中引入了重复注解,表示一 个注解在同一个位置可以重复使用多次

/**
 * *自定义可重复的注解
 */
@Repeatable(RoleAnnotions.class)
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface MyAnnotation{
    
        //定义角色属性
        String role(); 
}
/**
 *  定义一个容器,可以包含若干的 MyAnnotation 注解
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface RoleAnnotions {

    MyAnnotation[] value();
}

/**
 * 使用重复注解修饰一个类
 */
@MyAnnotation(role="Husband")
@MyAnnotation(role="Son")
@MyAnnotation(role="Father")
public class Person{

}
/**
 *  通过反射读取可重复注解的信息
 */
public class Test02 {

    public static void main(String[] args) {

        //创建 Class 对象
        Class<?> claxx = Person.class;

        //获得指定的自定义注解
        MyAnnotation[] myAnnotations = claxx.getDeclaredAnnotationsByType(MyAnnotation.class);

        //遍历数组,打印角色属性
        for (MyAnnotation annotation : myAnnotations) {
            System.out.println(annotation.role());
        }
    }
}

3 增加反射方法参数

  在 JDK8 中增加了 Parameter 参数类,可以通过反射拿到方法的参数。

/**
 * 定义类和方法
 */
public class MyClass {
    public void m1(int x, int y){}

    public void m2(String text, double num){}
}

  反射方法的参数类型和名称

/**
 * 反射方法中参数
 *  需要在编译时使用-parameters参数
 * Author : 动力节点老崔
 */
public class Test {
    public static void main(String[] args) {
    
        //1)创建Class对象
        Class<?> claxx = MyClass.class;

        //2)反射所有的方法
        Method[] declaredMethods = claxx.getDeclaredMethods();
        for( Method   method : declaredMethods ){
            //方法的修饰符
            int mod = method.getModifiers();
            System.out.print(Modifier.toString(mod) + " ");
            //方法返回值类型
            Class<?> returnType = method.getReturnType();
            System.out.print( returnType.getSimpleName() + " ");
            //方法名
            System.out.print( method.getName());

            //方法参数
            System.out.print("(");
            Parameter[] parameters = method.getParameters();
            for(int i = 0 ; i < parameters.length; i++){
                System.out.print( parameters[i].getType().getSimpleName() + " ");
                System.out.print( parameters[i].getName());
                //参数之间使用逗号分隔
                if ( i < parameters.length - 1 ){
                    System.out.print(",");
                }
            }

            System.out.println(");");
        }

    }
}

  结果:

public void m1(int arg0,int arg1);

public void m2(String arg0,double arg1);

  这是因为编译器编译时自动把参数忽略掉了,所以在编译时指定参数即可:
在编译时使用-parameters 参数

JDK8新特性之default、扩展注解、反射方法参数、hashmap性能提升_第1张图片
  重新编译后的结果:

public void m1(int x,int y);

public void m2(String text,double num);

4 对 HashMap 性能的提升

JDK8新特性之default、扩展注解、反射方法参数、hashmap性能提升_第2张图片

5 新增时间的操作类

public class Test {
    public static void main(String[] args) {


        //1)LocalDate日期类
        LocalDate date = LocalDate.now();   //当前日期
        System.out.println( date );     //2019-04-24
        System.out.println("==========================1=====================");

        //2)当前时间
        LocalTime time = LocalTime.now();
        System.out.println( time );     //19:50:35.344
        System.out.println("==========================2=====================");

        //3)日期与时间
        LocalDateTime now = LocalDateTime.now();
        System.out.println(now);        //2019-04-24T19:51:03.726
        System.out.println("==========================3=====================");

        //4)返回当前日期的各个属性值
        System.out.println( now.getYear());
        System.out.println( now.getMonthValue());
        System.out.println( now.getDayOfMonth());
        System.out.println( now.getHour());
        System.out.println( now.getMinute());
        System.out.println( now.getSecond());
        System.out.println( now.getNano());     //在毫秒数后面添加6个0
        System.out.println("==========================4=====================");

        //5)自定义时间
        LocalDateTime another = LocalDateTime.of(2100, 10, 12, 8, 58, 28);
        System.out.println( another );
        System.out.println("==========================5=====================");

        //6)使用plus增加时间, minus可以减少时间
        another = another.plusYears(1);
        System.out.println(another);

        another = another.plusMonths(1);
        System.out.println(another);

        another = another.plusDays(1);
        System.out.println(another);

        another = another.plusHours(1);
        System.out.println(another);

        another = another.plusMinutes(1);
        System.out.println(another);

        another = another.plusSeconds(1);
        System.out.println(another);

        another = another.plus(10, ChronoUnit.YEARS);
        System.out.println(another);

        System.out.println("==========================6=====================");

        //7)设置时间
        another = another.withYear(2088);
        another = another.withMonth(7);
        System.out.println( another);
        System.out.println("==========================7=====================");

        //8)判断星期几
        System.out.println( another.getDayOfWeek());
        System.out.println("==========================8=====================");

        //9)把日期转换为指定格式的字符串
        DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG);
        //LocalDateTime类中有一个format( DateTimeFormatter) 实例方法可以把日期转换为指定格式字符串
        System.out.println( now.format(formatter) );        //2019年4月24日 下午08时03分28秒

        System.out.println("==========================9=====================");

        formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT);
        System.out.println( now.format(formatter));     //19-4-24 下午8:03

        //自定义日期格式: y年, M月 d日 H小时 m分钟 s秒 S毫秒
        formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss SSS");
        System.out.println( now.format(formatter));  //2019年04月24日 20:05:16 338

        //10)把字符串转换为日期
        String text = "2089年8月12日 8:28:58";
        formatter = DateTimeFormatter.ofPattern("yyyy年M月dd日 H:mm:ss");
        // LocalDateTime.parse(text, formatter)静态方法,可以把text文件以formatter格式转换为日期对象
        another = LocalDateTime.parse(text, formatter);
        System.out.println(another);
        System.out.println("==========================10=====================");

    }
}

结果

2019-07-06
======1=
16:57:43.286
======2=
2019-07-06T16:57:43.286
======3=
2019
7
6
16
57
43
286000000
======4=
2100-10-12T08:58:28
======5=
2101-10-12T08:58:28
2101-11-12T08:58:28
2101-11-13T08:58:28
2101-11-13T09:58:28
2101-11-13T09:59:28
2101-11-13T09:59:29
2111-11-13T09:59:29
======6=
2088-07-13T09:59:29
======7=
TUESDAY
======8=
2019年7月6日 下午04时57分43秒
======9=
19-7-6 下午4:57
2019年07月06日 16:57:43 286
2089-08-12T08:28:58
======10=

你可能感兴趣的:(JDK8)