Java8揭秘(三)Default 方法
2014-04-21 01:46
393 查看
第二章Default方法
为什么要有Default方法
在Java8发布之际,有件事情就显得非常重要,即在不破坏java现有实现架构的情况下能往接口里增加新方法。引入Default方法到Java8,正是为了这个目的:优化接口的同时,避免跟现有实现架构的兼容问题。看下面例子:List<?>list=... list.forEach(...);//Lambdacodegoeshere |
这样,即使我们把Lambda表达式引入到java8中,但是因为不能牺牲向后兼容,而不可以把Lambda表达式和标准集合类库结合使用的话,会真的让人很泄气。
为了解决上述问题,引入了一个新的概念,即虚拟扩展方法(Virtualextensionmethods),通常也称之为defender方法,它目前可以添加到接口中,为声明的方法提供默认的实现。
简单地说,Java接口现在可以有非抽象方法了。Default方法带来的好处是,往接口新增一个Default方法,而不破坏现有的实现架构。
尽管如此,Default方法不适合过多使用,但是对于Java集合API的优化升级,并达到无缝地结合Lambda表达式来说,Default方法是至关重要的特性。
Default方法入门
让我们从最简单可行的例子开始:下面代码定义了接口A,以及实现了接口A的Clazz类:publicinterfaceA{ defaultvoidfoo(){ System.out.println("CallingA.foo()"); } } publicclassClazzimplementsA{} |
上例的客户端代码如下:
Clazzclazz=newClazz(); clazz.foo();//CallingA.foo() |
让我们用上一个例子来解释上述情况,代码如下所示:
publicinterfaceA{ defaultvoidfoo(){ System.out.println("CallingA.foo()"); } } publicinterfaceB{ defaultvoidfoo(){ System.out.println("CallingB.foo()"); } } publicclassClazzimplementsA,B{} |
java:classClazzinheritsunrelateddefaultsforfoo()fromtypesAandB
为了修复错误,在Clazz中,我们手工地覆写掉冲突的方法来处理这个问题,如下所示:
publicclassClazzimplementsA,B{ publicvoidfoo(){} } |
publicclassClazzimplementsA,B{ publicvoidfoo(){ A.super.foo(); } } |
@FunctionalInterfacepublicinterfaceIterable{ Iteratoriterator(); defaultvoidforEach(Consumer<?superT>action){ Objects.requireNonNull(action); for(Tt:this){ action.accept(t); } } } |
List<?>list=... list.forEach(System.out::println); |
方法调用
我们来看看实际上是如何调用default方法的。从客户端代码角度来看,default方法只不过都是初始化的抽象方法。因此default方法也叫-虚拟扩展方法。如果出现上例中的那个类,该类实现了带default方法的接口,那么调用default方法的客户端代码会在调用端生成invokeinterface。如下所示
Aclazz=newClazz(); clazz.foo();//invokeinterfacefoo() Clazzclazz=newClazz(); clazz.foo();//invokevirtualfoo() |
publicclassClazzimplementsA,B{ publicvoidfoo(){ A.super.foo();//invokespecialfoo() } } |
publicvoidfoo();
Code:
0:aload_0
1:invokespecial#2//InterfaceMethodA.foo:()V
4:return
如上面所示的,invokespecial指令用来调用接口中定义的方法foo()。这从字节码的角度看也是新东西,因为先前你进行方法调用,仅是通过指向父类的super而不是指向父接口的。
总结
Default方法加入到java中,这是引人关注的事情。Default方法可以认为是Lambda表达式和JDK类库之间的桥梁。引入Default方法的主要目的是为了升级标准JDK接口,另外也是为了我们最终能在Java8中顺畅使用Lambda表达式。相关文章推荐
- Java8揭秘(三)Default 方法
- Java8揭秘(三)Default 方法
- Java8 新特性 接口中的default方法
- AjaxControlToolkit的安装使用方法(转)2010年05月03日 星期一 10:54Ajax 最好最新的资源网:http://ajax.asp.net/downloads/default.aspx上面有所有Ajax最新的
- 【jQuery】事件- isDefaultPrevented() 方法
- MySQL5.0+提示字段没有默认值(doesn’t have a default value)的解决方法
- error:Implicit super constructor Object() is undefined for default constructor..的解决方法
- jquery事件preventDefault()方法用法实例
- Python 字典(Dictionary) setdefault()方法
- Field 'id' doesn't have a default value问题解决方法
- event.preventDefault方法的介绍
- Java 8新特性——default方法(defender方法)介绍
- 解决第三方类库无法通过armv7s编译的方法、添加Default-568h@2x.png
- [iphone][xcode]包含iphone4在内的icon,default及图片处理方法
- 为应用程序池 ''DefaultAppPool'' 提供服务的进程意外终止。进程 ID 是 ''xxx''问题的解决方法
- Project has no default.properties file! Edit the project properties to set one.错误解决方法
- Field 'id' doesn't have a default value问题解决方法
- 错误:java.security.InvalidKeyException: Illegal key size or default parameters解决方法
- error C4430: missing type specifier - int assumed. Note: C++ does not support default-int 解决方法
- 错误:java.security.InvalidKeyException: Illegal key size or default parameters解决方法