1 原生Base64 API
对应Base64的操作,没必要非要用第三方库了。java8内置的Base64 API位于 : java.util.Base64
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| byte[] bs = Base64.getEncoder().encode("java 8".getBytes(Charset.forName("UTF-8"))); System.out.println(new String(bs)); String string = Base64.getEncoder().encodeToString("java 8".getBytes(Charset.forName("UTF-8"))); System.out.println(string); byte[] bs2 = Base64.getDecoder().decode(bs); System.out.println(new String(bs2));
|
2 为NPE而生的Optional容器
为空指针而生的Optional,貌似N就之前就在 google的 工具类 Guava
中出现了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| public final class Optional<T> { private final T value; private Optional(T value) { this.value = Objects.requireNonNull(value); } private Optional() { this.value = null; } 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 2 3 4 5 6 7 8
| Optional<Object> empty = Optional.empty(); Optional.of(T value); ofNullable(T value);
|
常用方法
- isPresent() : 如果值存在返回true,否则返回false
- get(): 容器内部有值则将其返回,否则抛出NoSuchElementException
- orElse(T other): 容器内部有值则将其返回,否则返回other
- orElseGet(Supplier<? extends T> other): 容器内部有值则将其返回,否则返回供给型接口other的返回值
- orElseThrow(Supplier<? extends X> exceptionSupplier): 容器内部有值则将其返回,否则抛出供给型接口other返回的异常
- filter(Predicate<? super T> predicate): 对容器中的值使用predicate过滤后,如果满足条件则返回包含该值的Optional,否则返回空Optional
- map(Function<? super T, ? extends U> mapper): 该方法的源码如下
1 2 3 4 5 6 7 8 9 10 11
| public<U> Optional<U> map(Function<? super T, ? extends U> mapper) { Objects.requireNonNull(mapper); if (!isPresent()) return empty(); else { return Optional.ofNullable(mapper.apply(value)); } }
|
使用Optional
先来看一种别扭的写法
1 2 3 4 5 6
| Optional<User> user = ......; if (user.isPresent()) { return user.get().getName(); } else { return "default Value"; }
|
其实,这样用和下面的写法没有任何区别:
1 2 3 4 5 6
| User user = ......; if (user != null) { return user.getName(); } else { return "default Value"; }
|
调用方法 isPresent()
, 其实和 obj!=null
是一模一样的。
有了Optional,像下面这样才比较优雅:
1 2
| Optional<User> user = ......; return user.map(User::getName).orElse("default Value");
|
再来看个例子
1 2 3 4 5 6 7 8 9
| public static class Person { private String name; private Addr addr; public static class Addr { private String city; private String street; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public String getPersonStreet(Person person) { return Optional.ofNullable(person) .map(p -> p.getAddr()) .map(a -> a.getStreet()) .orElse("NotFound"); } 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public interface Foo { Integer max = 10000; String get(); static String bar() { return "haha"; } default String hello() { return "hello"; } }
|
这样一来,有点类似于多继承了,但是可能会有冲突:
- 类优先原则
- 实现的多个接口中的方法若有冲突,只能实现一个,其他的必须舍弃
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| 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() { 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(); cat.walk(); } }
|
4 可重复的注解
在jdk1.8之前,java中的注解不能直接重复出现在同一个被他修饰的方法或属性上。只能通过数组或者其他方式来变向的实现这个需求。
在jdk1.8里,可以让注解在同一个被修饰的方法或属性上重复出现。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| 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); Arrays.stream(annotations).forEach(System.out::println); } }
|
5 JavaScript引擎
1 2 3 4 5 6 7 8
| 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);"); System.out.println("out: " + ret); }
|
6 JVM内存模型变化
永久带被移除,引入了Metaspace。
详情可参看: http://blog.csdn.net/hylexus/article/details/53771460