Java8新特性

自己理解的java8的几个新特性。

首先,java8的新特性只有在编译等级为1.8的时候才能编译不报错,如果只是安装了jdk1.8,但是工程编译等级不到1.8,是编译不通过的。
下面就自己理解与测试,描述java8新特性,有增加后续补充。

1.接口的默认方法与静态方法Java8中,接口不再只能包含抽象方法,而可以有已经默认实现的方法和已经实现的静态方法。

默认方法:使用default修饰符修饰,此修饰符并不是方法访问限制修饰符,该方法访问权限依然是public,可以任意访问的,不过其不再抽象,必须在接口中就进行实现静态方法:Java8中添加了静态方法,静态方法也必须进行实现。而且该接口的静态方法只能通过Interface.method即定义接口类型直接调用方式调用,而不能被实现类对象甚至派生类型调用,即接口的静态方法不可被覆盖和继承

示例代码如下所示:注释的方法是无法通过编译的,因为并不满足java8的语法限制

 

 

 1 public interface WithDefaultMethdIntf {
 2     
 3     public void printSth();
 4 
 5     default void printIntMethod() {
 6         System.out.println("this is from the interface");
 7     }
 8     
 9     default void printIntM2() {
10         System.out.println("this is from the interface ,will be override");
11     }
12     
13     /**
14      * default methods in interface must have a body
15      */
16     //default void printIntM3();
17     
18 
19     static void printOfStatic(){
20         System.out.println("this is static method in interface ");
21     }
22     
23     
24     /**
25      * static method in interface can not be abstract
26      */
27     //static void printOfStaticM3();
28 }

 

接口的派生类型如下

 

 1 class WithDefaultMethodIntfSon implements WithDefaultMethdIntf {
 2 
 3     @Override
 4     public void printSth() {
 5         System.out.println("this print from son");
 6     }
 7 
 8     @Override
 9     public void printIntM2() {
10         System.out.println("this print from son override intf method 2");
11     }
12     
13 }
14 
15 interface WithDefaultMethodIntfSonInft extends WithDefaultMethdIntf{
16 
17     /**
18      * same name static method can defined in son type(class or interface),but is not override
19      */
20     //@Override
21     static void printOfStatic(){
22         System.out.println("this is static method in interface ");
23     }
24     
25     @Override
26     default void printSth(){
27         System.out.println("abstract method in interface can be default in son interface");
28     };
29 }

 

 

 

 下面是调用点的测试:

 1     @Test
 2     public void testDefualtMethod() {
 3         WithDefaultMethdIntf inst = new WithDefaultMethodIntfSon();
 4         // this call the default method in interface
 5         inst.printIntMethod();
 6         
 7         // this call the method in son ,which overrides the interface method
 8         inst.printIntM2();
 9         
10         // this call the method in son
11         inst.printSth();
12         
13         //This static method of interface WithDefaultMethdIntf can only be accessed as WithDefaultMethdIntf.printOfStatic
14          //inst.printOfStatic();
15         
16         WithDefaultMethdIntf.printOfStatic();
17         
18     }

打印结果为:

this is from the interface
this print from son override intf method 2
this print from son
this is static method in interface

 

2.函数式接口

函数式接口就是打上@FunctionalInterface后不会报错的接口,该接口只包含一个抽象方法。由于默认方法和静态方法都不是抽象的,因此一个函数式接口可以包含多个默认方法和静态方法。另外,只包含一个抽象方法的抽象类,是不能作为函数式接口的,函数式接口只能是接口类型。

 1 @FunctionalInterface
 2 public interface WithDefaultMethdIntf {
 3     
 4     public void printSth();
 5 
 6     default void printIntMethod() {
 7         System.out.println("this is from the interface");
 8     }
 9     
10     default void printIntM2() {
11         System.out.println("this is from the interface ,will be override");
12     }
13     
14     /**
15      * default methods in interface must have a body
16      */
17     //default void printIntM3();
18     
19 
20     static void printOfStatic(){
21         System.out.println("this is static method in interface ");
22     }
23     
24     static void printOfStatic2(){
25         System.out.println("this is static method2 in interface ");
26     }
27     
28     /**
29      * static method in interface can not be abstract
30      */
31     //static void printOfStaticM3();
32 }
33 
34 
35 /**
36  * @author liuming
37  *Invalid '@FunctionalInterface' annotation; FunctionalIntfTest is not a functional interface
38  */
39 //@FunctionalInterface
40 public interface FunctionalIntfTest {
41     void dosthone();
42     void dosthTwo();
43 }
44 
45 /**
46  * @author liuming
47  *Invalid '@FunctionalInterface' annotation; LambdaClassTest is not a functional interface
48  */
49 //@FunctionalInterface
50 public abstract class LambdaClassTest {
51     abstract void classMethodTest();
52 }

 

对于函数式接口,甚至可以不在方法参数中定义,直接使用dambda表达式获得函数式接口实例对象。下面的写法都是正确写法

        //使用方法引用可以直接生成函数式接口对象
        Object inst = new Object();
        Supplier<String> stringSupplier = inst::toString;

        //可以直接使用lambda表达式实例化函数式接口对象
        Supplier<String> stringSupplier2 = () -> "test";
        Comparable<Object> objectComparable = (a) -> (hashCode() - a.hashCode());

        //可以使用强转在引用时如果出现语义冲突,可以使用强转声明表达式的结果类型
        System.out.println((Supplier<String>) inst::toString);
        System.out.println((Supplier<String>) () -> "test");

 

 

3.lambda表达式

lambda表达式对我理解来说实际就是函数接口实例化的特有书写形式

当调用一个方法时,如果其参数为函数式接口,那么就可以使用lambda表达式作为参数传入。

冲突:当一个类有两个同名方法,由两个不同的函数式接口作为参数,且这两个接口的抽象方法相同,编译器会无法判断实例化为哪个接口,这时可以通过强转说明是哪个类型的实例化。

lambda表达式格式:(参数列表)->{实现内容return}

a.参数列表可以可以省略参数类型,省略时可能存在冲突。无参数时,也需要保留括号

b.实现内容如果只有一行,可以省略大括号

 

 1     @Test
 2     public void testLambda() {
 3         String sa[] = { "c", "b", "a" };
 4         Arrays.sort(sa, (a, b) -> a.compareTo(b));
 5         for (String string : sa) {
 6             System.out.print(string);
 7         }
 8         System.out.println("");
 9         
10         Arrays.asList( "p", "k", "u","f", "o", "r","k").forEach(a->System.out.print(a));
11         System.out.println("");
12         
13         //The method runRunnable(Runnable) is ambiguous for the type Java8Feture
14         //runRunnable(()->System.out.println("parse to Runnable run"));
15         
16         runRunnable((Runnable)()->System.out.println("parse to Runnable run"));
17         
18         System.out.println("---------test my self inft inst by lambda");
19         
20         runRunnable((MyRunnable)()->System.out.println("parse to MyRunnable run"));
21         
22         myLambdaIntf(()->System.out.println("WithDefaultMethdIntf"));
23         
24         // The target type of this expression must be a functional interface
25         //functionalClassTest(()->System.out.println("WithDefaultMethdIntf"));
26         
27     }

 

4.方法与构造函数引用

 貌似只为lambda表达式服务,类似于lambda表达式简写,而且有参数局限,后续研究

 

5.stream流式操作

  可参考的一篇文章: https://www.ibm.com/developerworks/cn/java/j-lo-java8streamapi/

  按照我的理解,stream流的特点有如下几点。

  1.获取方式

    a.从集合或数组中生成,如:Collection实例对象调用Collection接口的默认方法stream或者parallelStream(并行执行,多核优势),Arrays.stream(T array) or Stream.of()

    b.通过Stream.generate(Supplier<T> s)从生产者接口实例获得,此时必须使用limit方法限制大小

    c.从一些工具类的方法中获取:

    • BufferedReader
      • java.io.BufferedReader.lines()
    • 静态工厂
      • java.util.stream.IntStream.range()
      • java.nio.file.Files.walk()
    • 其它
      • Random.ints()
      • BitSet.stream()
      • Pattern.splitAsStream(java.lang.CharSequence)
      • JarFile.stream()

  2.操作方法分为Intermediate和Terminal模式,即stream的方法

    a.Intermediate模式相当于记录要进行的操作,并不立即进行处理,此类方法一般返回类型还是stream

    b.Terminal模式方法调用时才开始进行处理,并且消耗stream,此类方法一般返回结果为期望的处理结果

    相当于对于一个数据集合,1次stream操作只进行一次集合遍历,每遍历到某个元素都会将所有Intermediate和Terminal操作执行一次,得到最终结果。

 

posted @ 2017-05-22 01:17  minggliu  阅读(301)  评论(0)    收藏  举报