Java 8新性能

Java8的新特性主要表现在:语言、编辑器、库、工具、运行时

一.语言

1.Lambda表达式

基本语法:parameter->expression body

  • 可选类型声明 - 无需声明参数的类型。编译器可以从该参数的值推断。
  • 可选大括号 - 表达式主体没有必要使用大括号,如果主体中含有一个单独的语句。
  • 可选圆括号参数 - 无需在括号中声明参数。对于多个参数,括号是必需的。
  • 可选return关键字 - 编译器会自动返回值,如果主体有一个表达式返回的值。花括号是必需的,以表明表达式返回一个值。如:
MathOperation addition = (int a, int b) -> a + b;
Arrays.asList( "a", "b", "d" ).forEach( e -> System.out.println( e ) );

2.函数接口

定义:只有一个函数的接口。这样的接口可以隐式转化为Lambda表达式。值得注意的是:默认方法和静态方法不会破坏函数接口的定义。

可以显示说明某个函数是函数接口。如:

@FunctionalInterface
public interface FunctionalDefaultMethods {
    void method();
        
    default void defaultMethod() {            
    }        
}

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

默认方法可以不破坏二进制兼容的情况下,往现有的接口中添加方法。即:不强求实现该接口的类实现这个默认方法。当然实现类也可以继承或重写这个默认方法。

但是静态方法和默认方法有一定的区别:

  • 静态方法不可以被继承。
  • 默认方法可以被继承、被重写。
  • 函数接口可以实现另一个函数接口。
  • 默认方法重新声明,则变为普通方法。

4.方法引用

构造器引用:语法是Class::new。值得注意的是,该构造器没有参数。如:HashSet::new。

静态方法引用:语法是Class::static_method。这个方法接受一个Class类型的参数。

特定类的任意对象的方法引用:语法是Class::method。这个方法没有参数。

特定对象的方法引用:语法是instance:method。这个方法接受一个instance对应的Class类型的参数。

5.重复注解

Java8允许在同一位置声明多个注解。重复注解机制需要使用@Repeatable注解。

public class RepeatingAnnotations {
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Filters{
        Filter[] value();
    }

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Repeatable(Filters.class)
    public @interface Filter{
        String value();
    }

    @Filter("filter1")
    @Filter("filter2")
    public interface Filterable{
    }

    public static void main(String[] args) {
        for(Filter filter: Filterable.class.getAnnotationsByType(Filter.class)){
            System.out.println(filter.value());
        }
    }
}

Filter使用@Repetable(Filers.class)修饰,Filters是存放Filter注解的容器。反射API提供getAnnotationByType()返回某个类型的重复注解。

6.更好的类型推断

7.拓宽了注解的使用场景。

注解可以使用到局部变量、接口类型、函数的异常定义等上。

二.编译器

为了在运行时获得方法的参数名称,Java8可以在语法层面(利用反射API和Parameter.getName()方法)、字节码层面(使用新的javac编译器以及-parameter参数)提供支持。

三.库

1.Optional

为了解决空指针异常问题。常用的方法有:

.isPresent()。如果存在值,返回true

.orElse()。如果有值,返回当前值,如果没有值,返回other。

.of()。如果不为null,返回一个指定值的Optional,否则报异常。

.ofNullable()。如果不为null,返回一个指定值的Optional,否则返回一个空的Optional。

.get()。如果有值,返回当前值,如果没有值,返回NoSuchElementException。

2.Stream

常用的方法:

.stream()。返回顺序流,集合作为其源。

.parallelStream()。返回并行数据流,集合作为其源。

.filter()。方法用于消除基于标准元素。

.map()。方法用于映射每个元素对应的结果

.forEach()。方法遍历流中的每一个元素。

.limit()。方法用于减少流的大小。

.sorted()。方法用于流排序。

.collect()。方法是终端操作,通常出现在管道传输结束标记流的结束。

public void test(){
        List strings=Arrays.asList("abc","","ba","efg","abcd","","jkl");
        List list=strings.stream().filter(n->!"".equals(n)).limit(3).collect(Collectors.toList());
        list.forEach(n->System.out.println(n));
    }

3.Date/Time

Clock:通过指定一个时区,获取当前时刻、日期与时间

LocalDateTime:包含了LocalDate和LocalTime,但是不包含ISO-8601日历系统中的时区信息。

ZonedDateTime:带时区日期时间处理。

ZonedDateTime date1 = ZonedDateTime.parse("2007-12-03T10:15:30+05:30[Asia/Karachi]");

ChronoUnit:可以代替Calendar的日期操作。

LocalDate today = LocalDate.now();
LocalDate nextWeek = today.plus(1, ChronoUnit.WEEKS);

Period:处理有关基于时间的日期数量。

LocalDate date1 = LocalDate.now();
LocalDate date2 = date1.plus(3, ChronoUnit.DAYS);
Period period = Period.between(date1, date2);

Duration:处理有关基于时间的时间量。

TemporarlAdjuster:做日期数学计算。

LocalDate date1 = LocalDate.now();
LocalDate nextTuesday = date1.with(TemporalAdjusters.next(DayOfWeek.TUESDAY));

4.Nashorn JavaScript引擎

可以在JVM上开发和运行JS。

ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName( "JavaScript" );
        
System.out.println( engine.getClass().getName() );
System.out.println( "Result:" + engine.eval( "function f() { return 1; }; f() + 1;" ) );

5.Based 64

inal String text = "Base64 finally in Java 8!";
final String encoded = Base64.getEncoder().encodeToString( text.getBytes( StandardCharsets.UTF_8 ) );
final String decoded = new String( Base64.getDecoder().decode( encoded ),StandardCharsets.UTF_8 );

6.并行数组

比较重要的方法是parallelSort。

long[] arrayOfLong=new long[20000];
Arrays.parallelSetAll(arrayOfLong,index->ThreadLocalRandom.current().nextInt(1000000));
Arrays.stream(arrayOfLong).limit(10).forEach(i-> System.out.print(i+""));
Arrays.parallelSort(arrayOfLong);
Arrays.stream(arrayOfLong).limit(10).forEach(i-> System.out.print(i+""));

7.并发性

四.工具

1.Nashorn引擎:jjs

jjs是一个基于标准Nashorn引擎的命令行工具,可以接受js源码并执行。如有一个func.js文件,可以通过jjs func.js执行js源码。

2.类依赖分析器:jdeps

输入.class文件、目录、jar包,就可以展示包层级和类层级的Java依赖关系。

jdeps org.springframework.core-3.0.5.RELEASE.jar

五.运行时

在java8中去掉了持久区,取而代之的是将原本要放在持久区的类元数据信息、字节码信息及static final的常量,转移到了计算机本地内存中。这样理论上说就不会出现java.lang.OutOfMemoryError: PermGen space的异常。

使用Metaspace(JEP 122)代替持久代(PermGen space)。在JVM参数方面,使用-XX:MetaSpaceSize和-XX:MaxMetaspaceSize代替原来的-XX:PermSize和-XX:MaxPermSize。

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(编程后端)