{"id":265,"date":"2011-11-08T23:22:50","date_gmt":"2011-11-08T23:22:50","guid":{"rendered":"http:\/\/choudhury.com\/blog\/?p=265"},"modified":"2012-02-09T01:39:45","modified_gmt":"2012-02-09T01:39:45","slug":"virtual-extension-methods","status":"publish","type":"post","link":"https:\/\/choudhury.com\/blog\/2011\/11\/08\/virtual-extension-methods\/","title":{"rendered":"Virtual Extension Methods"},"content":{"rendered":"<p>To update the existing Collections library for <a href=\"\/?p=203\" title=\"Lambda\">lamba <\/a>(proposed for Java 8), another new feature proposed for Java 8 is Virtual Extension Methods.<\/p>\n<p>One of the problems of using interfaces, is that you are unable to add new methods to interfaces without potentially causing problems for existing libraries that were already developed\/compiled against the original interface definition. So unless you can rebuild those libraries against your updated Interface definition, you&#8217;re stuck! This is where Virtual Extension Methods will come to the rescue.<\/p>\n<p>The Scenario<\/p>\n<p>An interface was created by Bob.<\/p>\n<div class=\"codecolorer-container java default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"java codecolorer\"><span class=\"kw1\">import<\/span> <span class=\"co2\">java.util.*<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n<span class=\"kw1\">public<\/span> <span class=\"kw1\">interface<\/span> DefenderMethod<span class=\"br0\">&#123;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; <span class=\"kw4\">void<\/span> method1<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/div>\n<p>Alice creates class DefenderMethodImpl  that implements DefenderMethod<\/p>\n<div class=\"codecolorer-container java default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"java codecolorer\"><span class=\"kw1\">import<\/span> <span class=\"co2\">java.util.*<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n<span class=\"kw1\">public<\/span> <span class=\"kw1\">class<\/span> DefenderMethodImpl <span class=\"kw1\">implements<\/span> DefenderMethod<span class=\"br0\">&#123;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp;@Override<br \/>\n&nbsp; &nbsp;<span class=\"kw1\">public<\/span> <span class=\"kw4\">void<\/span> method1<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; <a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+system\"><span class=\"kw3\">System<\/span><\/a>.<span class=\"me1\">out<\/span>.<span class=\"me1\">println<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;method [implementedMethod1] called&quot;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp;<span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; &nbsp;<br \/>\n&nbsp; &nbsp; <br \/>\n&nbsp; &nbsp;<span class=\"kw1\">public<\/span> <span class=\"kw1\">static<\/span> <span class=\"kw4\">void<\/span> main<span class=\"br0\">&#40;<\/span><a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+string\"><span class=\"kw3\">String<\/span><\/a><span class=\"br0\">&#91;<\/span><span class=\"br0\">&#93;<\/span> args<span class=\"br0\">&#41;<\/span><span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; DefenderMethod defender<span class=\"sy0\">=<\/span> <span class=\"kw1\">new<\/span> DefenderMethodImpl<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; defender.<span class=\"me1\">method1<\/span><span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp;<span class=\"br0\">&#125;<\/span><br \/>\n&nbsp; &nbsp; <br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/div>\n<p>Now Bob wants to add a new methods to the interface, this might cause problems for Alice if she pulls in Bobs latest interfaces updates, she may get runtime errors if her class runs against against the updated interfaces, or if she re-compiles, she will get compilation errors which need to be resolved.<\/p>\n<p>This is where virtual extension methods will be very useful, for  methods on the interface, we can specify a default implementation for the method, this means we maintain binary and source compatibility for existing classes that were  compiled against this interface. So now Bob can add new virtual extension methods to his interface without worrying about causing problems for Alice, thus preserving both binary (Alice doesn&#8217;t need to recompile) and source compatibility (Alice doesn&#8217;t need to change her code).<\/p>\n<p>To implement a virtual extension method, you add &#8220;default&#8221; after the method signature, followed by the actual static method that be used as the default implementation.<\/p>\n<div class=\"codecolorer-container java default\" style=\"overflow:auto;white-space:nowrap;\"><div class=\"java codecolorer\"><span class=\"kw1\">import<\/span> <span class=\"co2\">java.util.*<\/span><span class=\"sy0\">;<\/span><br \/>\n<br \/>\n<span class=\"kw1\">public<\/span> <span class=\"kw1\">interface<\/span> DefenderMethod<span class=\"br0\">&#123;<\/span><br \/>\n<br \/>\n&nbsp; &nbsp; <span class=\"kw4\">void<\/span> method1<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <br \/>\n&nbsp; &nbsp; <span class=\"kw4\">int<\/span> method2<span class=\"br0\">&#40;<\/span><span class=\"kw4\">int<\/span> val<span class=\"br0\">&#41;<\/span> <span class=\"kw1\">default<\/span> &nbsp;<span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <a href=\"http:\/\/www.google.com\/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+system\"><span class=\"kw3\">System<\/span><\/a>.<span class=\"me1\">out<\/span>.<span class=\"me1\">println<\/span><span class=\"br0\">&#40;<\/span><span class=\"st0\">&quot;default method invoked called with args &quot;<\/span><span class=\"sy0\">+<\/span>val<span class=\"br0\">&#41;<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw1\">return<\/span> val<span class=\"sy0\">+<\/span><span class=\"nu0\">4<\/span><span class=\"sy0\">;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"br0\">&#125;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/div>\n<p>If the interface (InterfaceFoo) is extended by another interface (InterfaceBar) , the default method of the extended interface (InterfaceBar) is preffered. If implementers of the class have defined the methods, these will be used in preference to the default method implementation.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>How does this compare to C# Extension Method?<\/strong> <\/p>\n<p>C# Extension Methods uses a compiler trick, the compiler when it sees you are calling an <a href=\"http:\/\/en.wikipedia.org\/wiki\/Extension_method\">extension method<\/a> (which is basically a static method whose first argument is the same type as the instance), even though the source code you write, looks like you are calling an instance method, the byte-code that is generated for this is actually a call to the static method, because this is not implemented as a VM feature, this is brittle compared to the virtual extension methods proposed for Java. The other difference is C# extension methods are only available in the site where the the extension method is imported, java extension methods will be available to all implementers of the interface.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>To update the existing Collections library for lamba (proposed for Java 8), another new feature proposed for Java 8 is Virtual Extension Methods. One of the problems of using interfaces, is that you are unable to add new methods to interfaces without potentially causing problems for existing libraries that were already developed\/compiled against the original &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/choudhury.com\/blog\/2011\/11\/08\/virtual-extension-methods\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Virtual Extension Methods&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[3],"tags":[],"class_list":["post-265","post","type-post","status-publish","format-standard","hentry","category-java"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/choudhury.com\/blog\/wp-json\/wp\/v2\/posts\/265","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/choudhury.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/choudhury.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/choudhury.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/choudhury.com\/blog\/wp-json\/wp\/v2\/comments?post=265"}],"version-history":[{"count":42,"href":"https:\/\/choudhury.com\/blog\/wp-json\/wp\/v2\/posts\/265\/revisions"}],"predecessor-version":[{"id":363,"href":"https:\/\/choudhury.com\/blog\/wp-json\/wp\/v2\/posts\/265\/revisions\/363"}],"wp:attachment":[{"href":"https:\/\/choudhury.com\/blog\/wp-json\/wp\/v2\/media?parent=265"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/choudhury.com\/blog\/wp-json\/wp\/v2\/categories?post=265"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/choudhury.com\/blog\/wp-json\/wp\/v2\/tags?post=265"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}