美文网首页程序员java学习记录
JAVA---注解、jdk1.8新特性

JAVA---注解、jdk1.8新特性

作者: 一花一世界yu | 来源:发表于2020-06-06 16:52 被阅读0次

    一、重点知识

    注解并无主动功能,主要功能就是给类和类的组成做标记,让编译器检查

    RetentionPolicy.CLASS是默认生命周期,没有被@Retention修饰的注解的生命周期都是这种策略。
    接口中default方法只能让实现类用

    static 定义的方法只能给接口用

    接口中只有一个抽象方法时,才可以用lambda表达式简写,这样的接口我们称为函数式接口

    只有有提示的时候编译器才能给lambda表达式补全

    函数接口实现匿名内部类的简写形式就是lambda表达式

    lambda表达式不能调用接口中的默认方法

    异常最重要的是名称,处理都以异常名为准

    二、重点问题

    注解部分重点内容:

    1、什么是注解,注解的作用

    2、如何自定义一个注解

    3、三种重要的元注解

    @target规定了注解的使用位置 @retention 规定注解的生命周期 @Repeatable 定义重复注解

    4、注解在实际中如何通过反射调用

    三课堂知识

    注解

    1. 定义:
      • 注解就是给代码中的某个成员做一个标记
      • 至于能不能发挥作用,主要看检测这个标记的功能
    2. 自定义注解
      • 写一个类, @interface
      • 元注解 : 用来给标记注解
        • @Target : 当前定义的注解以后可以使用在什么位置
        • @Retention : 当前注解保留到什么时候

    一. default关键字

    1. 定义

      • 1.8中允许我们给接口添加一个非抽象的方法实现, 在方法使用default关键字就可以了,这个特征又叫做拓展方法
    2. 演示

      public interface MyInterface {
       //使用default的关键字
       public default void method(){
           System.out.println("你好....");
       }
      }
      
    3. 注意事项

      • 我们都知道, java之所以支持多实现就是应为接口中没有具体的逻辑代码, 不会造成冲突的问题, 那么1.8之后我们可以在接口中编写具体的逻辑代码了,那么多实现的时候会冲突吗 ?
      • 肯定会冲突的,所以为了解决这个问题, 编译器要求如果多实现的时候出现了相同名称的非抽象方法的话,子类就必须重写这个方法
    4. 多实现

      public class Demo implements MyInterface,MyInterface2{
      
       @Override
       public void method() {
           System.out.println("子类必须重写多个接口中相同名称的非抽象方法");
              MyInterface.super.method();
       }
      
      }
      

    二. 接口中的静态方法

    1. 定义

      • 在接口中定义一个静态的方法, 可以有具体的代码实现
    2. 演示

      public interface MyInterface {
       
       //静态方法 只能接口自己使用
       //接口中的静态方法权限必须是public的, 默认加上public
       static void method3(){
           System.out.println("我是接口中的静态方法");
       }
      }
      
    3. 注意事项

      • 子类无法使用接口中的静态方法
      • 接口中的静态方法的权限必须是公共的,可以不写,默认是公共的

    三. lambda表达式

    1. 定义

      • 一种简写形式,格式精简, 很酷
      • 每一个lambda的表达都对应一个类型,通常是接口类型的
      • 适用于函数式接口(只有一个抽象方法的接口)
    2. 格式

      • (参数...) -> {执行代码} 返回一个可用的对象
      • 当只有一句代码时,大括号可以省略, 不建议省略
    3. 演示

      public static void main(String[] args) {
       List<String> list = Arrays.asList("hh","dd","ni","kk");
       
       //之前的写法
       Collections.sort(list,new Comparator<String>() {
           public int compare(String o1, String o2) {
               
               return o1.compareTo(o2);
           }
       });
       
       //lambda表达式的写法
       Collections.sort(list, (String a,String b)->{
           return a.compareTo(b);
       });
       
       System.out.println(list);
      
      }
      
    4. 方法的引用

      • 使用 : : 来引用一个类的方法
      public interface Doing<K,T> {
       
       public T doing(K k);
      }
      
      
      public static void main(String[] args) {
       //调用类中的静态方法来处理接口中方法上的参数
       Doing<String, Integer> d = Integer::valueOf;
       Integer integer = d.doing("123");
       System.out.println(integer);
      }
      
      public static void main(String[] args) {
       //调用对象的方法
       Doing<String, Integer> d = "java"::lastIndexOf;
       Integer i = d.doing("v");
       System.out.println(i);
      }
      
    5. 构造方法的引用

      • 用new关键字来代替构造方法
      public class Person {
       String name;
      
        Person(String name) {
           super();
           this.name = name;
       }
      
       @Override
       public String toString() {
           return "Person [name=" + name + "]";
       }
      
      }
      
      public static void main(String[] args) {
       //引用对象的构造方法
       Doing<String, Person> d = Person::new;
       Person person = d.doing("小明");
       
       System.out.println(person);
      }
      
    6. 注意事项

      • lambda表达式指向的接口必须和调用的方法的参数一致,也就是说相当于是接口实现类中的方法调用你指向的方法
      • lambda表达式中访问外层作用域和老版本的匿名对象的方式很相似, 你可以直接访问标记了final的外层局部变量, 或者示例的字段以及静态变量
      • lambda表达式中无法访问接口中的默认方法(就是被default修饰的方法)

    四. Stream接口

    1. 定义

      • 表示能应用在一组元素上一次执行的操作序列
      • 其实就是找了一个地方将执行了某个方法后剩下的元素存放起来
      • 提供了许多操作集合的方法,而且原集合数据不受影响
    2. 常用的方法

      • filter 过滤
      • sorted 排序
      • map 转化
      • match 匹配
      • count 计数
    3. 演示

      public static void main(String[] args) {
       List<String> stringCollection = new ArrayList<>();
       stringCollection.add("ddd2");
       stringCollection.add("aaa2");
       stringCollection.add("bbb1");
       stringCollection.add("aaa1");
       stringCollection.add("bbb3");
       stringCollection.add("ccc");
       stringCollection.add("bbb2");
       stringCollection.add("ddd1");
       
       //过滤出以a开头的元素并遍历
       stringCollection.stream().
       filter((s)->s.startsWith("a"))
       .forEach(System.out::println);;
      }
      
    4. 并行

      • 并行Stream可以在多个线程上同时执行
      public static void main(String[] args) {
       int max = 1000000;
       List<String> values = new ArrayList<>(max);
       for (int i = 0; i < max; i++) {
           //创建随机id
           UUID uuid = UUID.randomUUID();
           values.add(uuid.toString());
       }
       
       long t1 = System.nanoTime();
       //获取并行的stream
       long count = values.parallelStream().sorted().count();
       System.out.println(count);
       
       long t2 = System.nanoTime();
       System.out.println(t2-t1);
      }
      

    五. Date

    1. 定义

      • java 8 在包java.time下包含了一组全新的时间日期API
    2. ZoneId

      • 定义时区
      public static void main(String[] args) {
       System.out.println(ZoneId.getAvailableZoneIds());
       //获取某个城市的时区
       ZoneId zone1 = ZoneId.of("Europe/Berlin");
       ZoneId zone2 = ZoneId.of("Asia/Shanghai");
       System.out.println(zone1.getRules());
       System.out.println(zone2.getRules());
      }
      
    3. LocalTime

      • 一个没有时区信息的时间,以设置的时区为准备
      public static void main(String[] args) {
       //获取所有的时区信息
       System.out.println(ZoneId.getAvailableZoneIds());
       //获取某个城市的时区
       ZoneId zone1 = ZoneId.of("Europe/Berlin");
       ZoneId zone2 = ZoneId.of("Asia/Shanghai");
       
       LocalTime now1 = LocalTime.now(zone1);
       LocalTime now2 = LocalTime.now(zone2);
       //判断时间1以是否在时间2之前
       System.out.println(now1.isBefore(now2));  // true
       //使用ChronoUnit计算两个时间差值 
       long hoursBetween = ChronoUnit.HOURS.between(now1, now2);
       long minutesBetween = ChronoUnit.MINUTES.between(now1, now2);
       System.out.println(hoursBetween);
       System.out.println(minutesBetween);
      }
      

    六.其他新特性

    1. 重复注解
    2. 可以将参数的名字保留到字节码中
    3. Nashorn引擎 : jjs , 可以执行js代码
    4. 移除了FermGen空间,用Metaspace代替
      • -XX:MetaSpaceSize与-XX:MaxMetaspaceSize被代替-XX:PermSize与-XX:MaxPermSize

    相关文章

      网友评论

        本文标题:JAVA---注解、jdk1.8新特性

        本文链接:https://www.haomeiwen.com/subject/dcgwzhtx.html