java8-04-其他特性
来源:互联网 发布:java 字符串排序 编辑:程序博客网 时间:2024/05/04 07:33
- 原生Base64 API
- 为NPE而生的Optional容器
- 获取Optional实例
- 常用方法
- 使用Optional
- 总结
- 升级版的interface
- 可重复的注解
- JavaScript引擎
- JVM内存模型变化
1 原生Base64 API
对应Base64的操作,没必要非要用第三方库了。java8内置的Base64 API位于 : java.util.Base64
// 编码 --> 字节数组byte[] bs = Base64.getEncoder().encode("java 8".getBytes(Charset.forName("UTF-8")));// amF2YSA4System.out.println(new String(bs));// 编码 --> 直接转为StringString string = Base64.getEncoder().encodeToString("java 8".getBytes(Charset.forName("UTF-8")));// amF2YSA4System.out.println(string);// 解码byte[] bs2 = Base64.getDecoder().decode(bs);// java 8System.out.println(new String(bs2));
2 为NPE而生的Optional容器
为空指针而生的Optional,貌似N就之前就在 google的 工具类 Guava
中出现了。
public final class Optional<T> { private final T value; private Optional(T value) { // value为null时,在这一步就会直接报错,可以快速定位到NPE发生的位置 this.value = Objects.requireNonNull(value); } private Optional() { this.value = null; } // 返回一个空的Optional实例 public static<T> Optional<T> empty() { @SuppressWarnings("unchecked") Optional<T> t = (Optional<T>) EMPTY; return t; } public static <T> Optional<T> of(T value) { return new Optional<>(value); } public static <T> Optional<T> ofNullable(T value) { return value == null ? empty() : of(value); } // ...}
其实就是一个容器类,将可能为空的对象包装在容器中。
获取Optional实例
构造器是私有的,可以通过以下方法获取其实例:
// 1. 返回一个空的Optional实例Optional<Object> empty = Optional.empty();// 2. 内部调用了有参数的构造器,因此value != null 的情况下才能正常返回Optional实例Optional.of(T value);// 3. value可以是nullofNullable(T value);
常用方法
- isPresent() : 如果值存在返回true,否则返回false
- get(): 容器内部有值则将其返回,否则抛出NoSuchElementException
- orElse(T other): 容器内部有值则将其返回,否则返回other
- orElseGet(Supplier
public<U> Optional<U> map(Function<? super T, ? extends U> mapper) { // mapper不能是null Objects.requireNonNull(mapper); // 容器内没有值,返回空Optional if (!isPresent()) return empty(); else { // 容器内有值,返回对容器中的值apply隐射函数后的值的Optional return Optional.ofNullable(mapper.apply(value)); }}
使用Optional
先来看一种别扭的写法
Optional<User> user = ......;if (user.isPresent()) {// 容器内部的对象存在就使用它 return user.get().getName();} else {// 否则返回默认值 return "default Value";}
其实,这样用和下面的写法没有任何区别:
User user = ......;if (user != null) { return user.getName();} else { return "default Value";}
调用方法 isPresent()
, 其实和 obj!=null
是一模一样的。
有了Optional,像下面这样才比较优雅:
Optional<User> user = ......;return user.map(User::getName).orElse("default Value");
再来看个例子
public static class Person { private String name; private Addr addr; public static class Addr { private String city; private String street; }}
// 获取用户的街道名,如果为空,返回"NotFound"public String getPersonStreet(Person person) { return Optional.ofNullable(person)// .map(p -> p.getAddr())// .map(a -> a.getStreet())// .orElse("NotFound");}// 没有Optional的时候,这个功能很可能就得这么写了public String getPersonStreet2(Person person) { if (person != null) { if (person.getAddr() != null) { if (person.getAddr().getStreet() == null) { return "NotFound"; } return person.getAddr().getStreet(); } } return "NotFound";}
总结
- Optional的出现,并不是能够避免NPE,只是能减少NPE的发生。-
- 在NPE发生时,Optional可以快速定位NPE的根源
同时,在使用Optional的时候,应该尽量避免那些不优雅的写法,不然Optional的出现及几乎没有任何意义了。鉴于此,有以下几点建议:
- 尽量不要直接调用
isPresent()/get()
方法 - 不建议将Optional作为成员变量/方法入参
- 应该尽量使用
map()/filter()/orElse()
等方法
3 升级版的interface
public interface Foo { // 传统的全区静态常量 Integer max = 10000; // 传统的抽象方法 String get(); // 静态方法(新特性) static String bar() { return "haha"; } // default修饰的实例方法(新特性) default String hello() { return "hello"; }}
这样一来,有点类似于多继承了,但是可能会有冲突:
- 类优先原则
- 实现的多个接口中的方法若有冲突,只能实现一个,其他的必须舍弃
public class InterfaceTest { static interface Walkable { default void walk() { System.out.println("walk() from Walkable"); } } static interface Speekable { default void speek() { System.out.println("walk() from Walkable"); } default void walk() { System.out.println("walk() from Walkable"); } } static class Dog implements Walkable, Speekable { @Override public void walk() { // 1. 只能选择多个同名default方法中的一个来实现,其余的必须舍弃 Speekable.super.walk(); } } static class Animal { public void walk() { System.out.println("walk() from Animal"); } } static class Cat extends Animal implements Walkable { } public static void main(String[] args) { Cat cat = new Cat(); // 2. 类优先原则,此处的walk()来自于父类Animal,而不是接口Walkable cat.walk(); // walk() from Animal }}
4 可重复的注解
在jdk1.8之前,java中的注解不能直接重复出现在同一个被他修饰的方法或属性上。只能通过数组或者其他方式来变向的实现这个需求。
在jdk1.8里,可以让注解在同一个被修饰的方法或属性上重复出现。
public class AnnotationTest { @Target({ ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @Repeatable(Roles.class) public static @interface Role { String value(); } @Target({ ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) public static @interface Roles { Role[] value(); } public static class RepeatableAnnotationTest { @Role("admin") @Role("user") public void doProcess() { } } public static void main(String[] args) throws Exception { RepeatableAnnotationTest obj = new RepeatableAnnotationTest(); Method method = obj.getClass().getDeclaredMethod("doProcess"); Role[] annotations = method.getAnnotationsByType(Role.class); // @cn.xxx$Role(value=admin) // @cn.xxx$Role(value=user) Arrays.stream(annotations).forEach(System.out::println); }}
5 JavaScript引擎
public static void main(String[] args) throws ScriptException { ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("JavaScript"); Object ret = engine.eval("function add(i,j){return i+j;} add(1,1);"); //out: 2.0 System.out.println("out: " + ret);}
6 JVM内存模型变化
永久带被移除,引入了Metaspace。
详情可参看: http://blog.csdn.net/hylexus/article/details/53771460
阅读全文
0 0
- java8-04-其他特性
- java8新特性_其他类库的变化
- Java8 特性
- Java8特性
- java8 特性
- Java8特性
- java8特性
- JAVA8 特性
- java8特性
- java8 lambda表达式-其他
- java8 新特性
- java8新特性 ---译
- Java8新特性教程
- Java8新特性学习
- JAVA8新特性
- Java8新特性详解
- JAVA8的新特性
- java8 新特性
- mysql时间维度表。
- 栈和队列
- hdu4333 Revolving Digits(kmp+exkmp)
- Mac 终端命令大全
- 算法系列——Word Break
- java8-04-其他特性
- 查看已结束的中国大学MOOC课程
- 【转】MySQL实现Oracle里的 rank()over(ORDER BY) 功能
- Java并发——Synchronized优化(轻量级锁、偏向锁)
- PAT B1048. 数字加密
- leetcode之Insert Interval 问题
- CSU---2017多校赛(13)---F Election
- 浅谈 ==和equals的区别,this和super的用法
- python3.5 如何在virtural env 下面使用libsvm