Java8 03 Optional、注解和接口

1、Optional

⑴ 概念

Optional<T>

    是一个容器类,可以表示一个值存在或者不存在,它里面有一个value属性用于指向传入的对象,一定程度上可以避免空指针异常

/**
 * If non-null, the value; if null, indicates no value is present
 */
private final T value;

⑵ API

⒈ of

public static <T> Optional<T> of(T value) {}

创建一个新的Optional容器对象,里面封装了传入的对象。注意:不能传递null值,否则会报NPE

⒉ ofNullable

public static <T> Optional<T> ofNullable(T value) {}

可以创建一个新的空的Optional容器对象,即可以传入null值。注意:空的Optional,在调用get方法获取值时,会抛出java.lang.NuSuchElementException

⒊ empty

public static<T> Optional<T> empty() {}

创建一个空的Optional容器对象

⒋ get

  public T get() {
      if (value == null) {
          throw new NoSuchElementException("No value present");
      }
      return value;
  }

获取Optional中的值

⒌ orElse

public T orElse(T other) {}

如果Optional里面没有封装值,则返回此方法传入的值

⒍ orElseGet

public T orElseGet(Supplier<? extends T> other) {}

如果Optional里面没有封装值,则返回此方法传入的供给型函数所返回的值

⒎ isPresent

   public boolean isPresent() {
     return value != null;
   }

判断Optional中是否包含值

⒏ map

public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {}

根据传入的函数式接口,返回对应数据类型(返回结果的类型或其子类)和封装了结果的Optional容器对象

⒐ flatMap

public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {}

根据传入的函数式接口,返回对应数据类型(Optional,泛型为返回结果的类型)和封装了结果的Optional容器对象

⑶ 示例

    Optional<String> optional = Optional.of("Hello");
    optional = optional.map((val) -> {return val.length() > 2 ? "Hi" : val;});
    System.out.println(optional.get());

public class Person {
    private String name;
}

    Optional<Person> optional = Optional.of(new Person("小明"));
    Optional<String> name = optional.flatMap((p) -> {return Optional.of(p.getName());});
    System.out.println(name.get());

2、重复注解和类型注解

⑴ 重复注解

⒈ 概念

JDK8允许同一个注解可以重复注释

⒉ API

    需要编写一个属性值为目标重复注解数组的注解,同时在目标重复注解上使用@Repeatable注解,将含有注解数组的注解传入即可
    注意:含有重复注解数组的注解的修饰目标(@Target)和运行存在时期(@Retention)都要一致,否则会报错

⒊ 示例

【重复注解】

@Repeatable(RepeatAnnotation.class) // 含有重复注解数组属性的注解
@Target(METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {

    String value();

}

【含有注解数组的注解】

@Target(METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RepeatAnnotation {

    MyAnnotation[] value();

}

【测试类】

public class TestAnnotation {

    @MyAnnotation("张三")
    @MyAnnotation("李四")
    public void method() { }

    public static void main(String[] args) {
        Class<TestAnnotation> clazz = TestAnnotation.class;
        Method method = null;
        try {
            method = clazz.getDeclaredMethod("method");
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        if (null != method) {
            MyAnnotation[] annotations = method.getDeclaredAnnotationsByType(MyAnnotation.class); // 获取注解数组
            for (int i = 0, len = annotations.length; i < len; i++) {
                System.out.println(annotations[i].value());
            }
        }
    }

}

⑵ 类型注解

    JDK8允许在方法形参前添加注解,在@Target中使用ElementType.TYPE_PARAMETER

3、接口的默认方法和静态方法

⑴ 默认方法

⒈ 概念

    JDK8中允许接口中包含有具体实现的方法(可以有多个),该方法被称为默认方法,通过default关键字来修饰

⒉ 示例

public interface MyInterface {
    default String hello(String name) {
        return "Hello:" + name;
    }
}

⑵ 类优先原则

⒈ 概念

    如果一个类同时继承了父类,实现了接口,而父类和接口中的默认方法同名时,则子类调用方法,优先使用父类的方法

⒉ 示例

【父类】

public class SuperClass {
    public String hello() {
        return "你好!";
    }
}

【接口】

public interface MyInterface {
    default String hello() {
        return "Hello!";
    }
}

【子类】

public class SubClass extends SuperClass implements MyInterface { }

【测试】

SubClass subClass = new SubClass();
String hello = subClass.hello();
System.out.println(hello); // 你好!

⑶ 接口冲突

⒈ 概念

    当实现的多个接口中,含有相同的默认方法,则需要实现类来指定要调用哪个接口的默认方法
    使用接口.super.方法名来指定

⒉ 示例

【接口1】

public interface MyInterface {
    default String hello() {return "Hello!";}
}

【接口2】

public interface MyInterface2 {
    default String hello() {return "Hi!";}
}

【实现类】

public class SubClass implements MyInterface, MyInterface2 {
    @Override
    public String hello() {
        return MyInterface2.super.hello(); // 调用接口MyInterface2的默认方法
    }
}

【测试】

SubClass subClass = new SubClass();
String hello = subClass.hello();
System.out.println(hello); // Hi!

⑷ 静态方法

⒈ 概念

JDK8中还允许接口中包含静态方法(可以有多个)

⒉ 示例

public interface MyInterface {
    static void hi() {
        System.out.println("Hi");
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值