Java 8-Lambdas(Notes)

(摘自https://www.oracle.com/technetwork/articles/java/architect-lambdas-part1-2080972.html)
1.Type inference.
One of the features that some other languages have been touting is the idea of type inference: that the compiler should be smart enough to figure out what the type parameters should be, rather than forcing the developer to retype the parameters.

If the target type is a Comparator, the objects passed in to the lambda must be strings (or some subtype); otherwise, the code wouldn’t compile in the first place. (This isn’t new, by the way—this is “Inheritance 101.”)

In this case, then, the String declarations in front of the lhs and rhs parameters are entirely redundant and, thanks to Java 8’s enhanced type inference features, they are entirely optional

Example:

public static void main(String... args) {
    Comparator<String> c =
      (lhs, rhs) ->
        {
          System.out.println("I am comparing" +
                             lhs + " to " + rhs);
          return lhs.compareTo(rhs);
        };
    int result = c.compare("Hello", "World");
  } 

The language specification will have precise rules as to when explicit lambda formal type declarations are needed, but for the most part, it’s proving to be the default, rather than the exception, that the parameter type declarations for a lambda expression can be left out completely.

One interesting side effect of Java’s lambda syntax is that for the first time in Java’s history, we find something that cannot be assigned to a reference of type Object—at least not without some help.

public static void main4(String... args) {
    Object o = () -> System.out.println("Howdy, world!");
      // will not compile
  } 

The compiler will complain that Object is not a functional interface, though the real problem is that the compiler can’t quite figure out which functional interface this lambda should implement: Runnable or something else? We can help the compiler with, as always, a cast.

public static void main4(String... args) {
    Object o = (Runnable) () -> System.out.println("Howdy, world!");
      // now we're all good
  } 

Recall from earlier that lambda syntax works with any interface, so a lambda that is inferred to a custom interface will also be inferred just as easily, as shown in Listing 9. Primitive types are equally as viable as their wrapper types in a lambda type signature, by the way

2.Lexical scoping
Lambdas, however, are lexically scoped, meaning that a lambda recognizes the immediate environment around its definition as the next outermost scope. So the lambda example in Listing 12 produces the same results as the second Hello nested class example in Listing 11 , but with a much more intuitive syntax

listing 10

class Hello {
  public Runnable r = new Runnable() {
      public void run() {
        System.out.println(this);
        System.out.println(toString());
      }
    };

  public String toString() {
    return "Hello's custom toString()";
  }
}

public class InnerClassExamples {
  public static void main(String... args) {
    Hello h = new Hello();
    h.r.run();
  }
} 

匿名内部类写法(listing 11):

class Hello {
  public Runnable r = new Runnable() {
      public void run() {
        System.out.println(Hello.this);
        System.out.println(Hello.this.toString());
      }
    };

  public String toString() {
    return "Hello's custom toString()";
  }
}

lambdas写法(listing 12):

class Hello {
  public Runnable r = () -> {
      System.out.println(this);
      System.out.println(toString());
    };

  public String toString() {
    return "Hello's custom toString()";
  }
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值