The next generation of Java: No inheritance Extensions (iii)

Source: Internet
Author: User
Tags closure exception handling extend inheritance

Groovy metaprogramming provides you with simple solutions to common problems

Java next-generation languages have many ways to extend existing classes and other artifacts, and the first two Java next-generation articles explore some of these approaches. In this installment, I'll go on to explore the Groovy meta programming techniques that implement extensions in multiple contexts.

In "No inheritance extensions, part 1th", when we discussed the use of class classes and expandometaclass as a mechanism to "apply" the new behavior to existing classes, I came across some Groovy meta programming features. The meta programming features in Groovy are deeper: they make it easier to integrate Java code, and can help you perform common tasks in a much simpler way than the Java language.

Interface casts (Interface coercion)

Interfaces are common semantic reuse mechanisms in the Java language. Other languages that try to integrate Java code in a concise way should provide an easy way to materialize the interface. In Groovy, classes can extend an interface through traditional Java methods. However, Groovy also makes it easy to easily cast closures and mappings into interface instances when it is convenient to do so.

Single Method cast

The Java code example in Listing 1 uses the FilenameFilter interface to locate the file:

Listing 1. Listing files in Java using the FilenameFilter interface

Import Java.io.File;
Import Java.io.FilenameFilter;
    
public class Listdirectories {public
    string[] Listdirectorynames (String root) {return
        new File (root). List (new FilenameFilter () {
            @Override public
            boolean Accept (File dir, String name) {return
                new file (name). Isdirectory ();}}
        );
    }

In Listing 1, I created a new anonymous inner class that overrides the Accept () method that specifies the filter condition. In Groovy, I can skip the step of creating a new class, casting only one closure to an interface, as shown in Listing 2:

Listing 2. Simulate the FilenameFilter interface in Groovy by using a closed-pack cast

New File ('. '). List (
    {File dir, String name-> new File (name). Isdirectory ()} as
     FilenameFilter). Each {println it}

In Listing 2, the list () method wants to use a filenamefilter instance as an argument. But I have created a closure that matches the accept () signature of the interface and implements the function of the interface in the body of the closure. After defining the closure, I cast the closure to the appropriate FilenameFilter instance by calling as FilenameFilter. Groovy's as operator materializes the closure as a class that implements the interface. This technique is very useful for a single method interface because there is a natural mapping between the method and the closure.

For interfaces that specify multiple methods, the materialized class invokes the same closure block for each method. But in rare cases, it is reasonable to handle all method calls with the same code. When you need to use more than one method, you can use a Map that contains a method name/closure pair instead of using a single closure.

Mapping

In Groovy, you can also use mappings to represent interfaces. The mapped key is a string representing the method name, and the key value is the code block that implements the method behavior. The example in Listing 3 materializes a map as a iterator instance:

Listing 3. Using mappings to materialize interfaces in Groovy

h = [hasnext:{h.i > 0}, next:{h.i--}]
h.i =
def iterator = h as iterator while
                                                      
(Iterator.hasnext ()) 
  print Iterator.next () + ","
//10, 9, 8, 7, 6, 5, 4, 3, 2, 1,

In Listing 3, I created a map (h) that includes the Hasnext and next keys and their respective blocks of code. Groovy assumes that the mapping key is a string, so I don't need to enclose the key in quotes. In each code block, I refer to the third key (i) of the H-map with the dot notation (h.i). This point symbol draws on the familiar object syntax, which is another example of syntax sugar in Groovy. Before using H as an iterator, no code block is executed, I must first make sure I has a value and then use H as an iterator. I use H.I = 10 to set the value of I. I then select H as a iterator and use a set of integers starting with 10.

By enabling Mappings to act as interface instances dynamically, Groovy greatly reduces some of the syntax problems that the Java language sometimes causes. This feature is a good illustration of how the next generation of Java language improves the developer experience.

Expandometaclass

As I mentioned in "No Inheritance extensions, part 1th", you can use Expandometaclass to add new methods to classes-including core classes, such as Object and String. Expandometaclass is also useful for other purposes, such as adding methods to object instances, and improving exception handling.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.