Androidsx Androidsx | android ninjas

 

Our blog, keeping you up-to-date on our latest news.

 

New features in Java 7

September 27, 2011 at 10:37 pm | blog, general | No comment

 

Here’s a summary of the most exciting features of the upcoming Java 7, which is of interest for the Java community and, consequently, for Android developers!

Language enhancements

Left to right type inference

This basically allows you to write Map<String, List<String>> retVal = new HashMap<>(); instead of Map<String, List<String>> retVal = new HashMap<String, List<String>>();, which is unnecessarily verbose.

It also infers the type of the return type: in a method whose signature is Map<String, List<String>> parseSomething() you can just return new HashMap<>(); and have the generics information inferred.

Using strings in switch statements

A natural extension of the switch statement. No longer do we have to map those strings to integers or enums, or write error-prone anidated if statements. It’s also a bit more efficient. For details see the Compilation section in the initial proposal.

Automatic resource management

Not much ago, we spent quite some time tracking down a bug because some DB connections were not closed. In complex infraestructures (i.e., where you use Spring, define several aspects to AspectJ, but sometimes you also program at the low level for optimization purposes), this is not always a trivial topic. Making sure you free this type of resources will no longer be necessary.

With Java 7, you can write

try (InputStream is = new FileInputStream(new File("foo.txt"))) {
    // read the file and do something with it
} catch (IOException e) {
    // handle this
}

instead of the more verbose, error-prone:

InputStream is = null;
try {
    is = FileInputStream(new File("foo.txt"));
    // read the file and do something with it
} catch (IOException e) {
    // handle this exception
} finally {
    if (is != null) {
        try {
            is.close();
        } catch (IOException ex) {
            // ignore this exception
        }
    }
}

You can thank the java.lang.AutoClosable interface, that has just one method: void close() throws Exception;.

Improvements to literals

Underscores: now you can write int billion = 1_000_000_000; instead of int billion = 1000000000; in order to make sure you don’t miscount the 0s.

Binary literals: this is an obvious extension to the literals, now you can write int yourInteger = 0b100100101; // 293 in decimal.

Improved exception handling

It’s common (and not necessarily a bad sign) to deal with different exception types in the same way. Instead of duplicating code by copy-pasting the same exception routine, now we can use the OR (\|) operator to group the exceptions:

try {
    methodThatThrowsThreeExceptions();
} catch (ExceptionOne e) {
    // deal with ExceptionOne
} catch (ExceptionTwo | ExceptionThree e) {
    // deal with ExceptionTwo and ExceptionThree, even if they belong to different hierarchies
}

Somewhat related to this is the ability to rethrow exceptions with their original types, with no wrapping, and without the need to catch them separately. The following piece of code, valid in Java 7,

private void throwExceptions() throws A, B, C {
    try {
        // some operation that's declared to throw A, B or C exceptions
    } catch (Exception e){
        LOGGER.error("Caught " + e + " and rethrowing it", e);
        throw e;
    }
}

is exactly equivalent to

private void throwExceptions() throws A, B, C {
    try {
        throwAccordingToIndex(new Random().nextInt(2));
    } catch (A e){
        LOGGER.error("Caught " + e + " and rethrowing it", e);
        throw e;
    }
    catch (B e){
        LOGGER.error("Caught " + e + " and rethrowing it", e);
        throw e;
    }
    catch (C e){
        LOGGER.error("Caught " + e + " and rethrowing it", e);
        throw e;
    }
}

You could argue that you should be using AOP here for the instrumentation of this exceptions, but that’s another topic.

New I/O API version (NIO.2)

You’ve probably had issues at some point in time with working with absolute/relative paths, especially for programs that run in different operating systems. Also, deleting/renaming files lead to issues, as it did working with symbolic links. This version aims at making these uses cases easier.

Path

The class java.nio.file.Path will probably become the most commonly used in this package. It’s a substitute of our beloved java.io.Path, but better. You can do FileSystems.getDefault().getPath("hello.txt");, or Paths.get("file.data").getParent();. It’s basically simpler to use, especially in an environment with different filesystems.

Files

This utility class provides over 50 utility methods, such as copy(), move(), newInputStream(), readAllBytes(), createSymbolicLink(), …

Watch Service API

This new API lets you listen to some system events related to files and directories, such as when a new file is created in a directory. For details, check out the javadoc of the WatchService.

Fork and Join

The fork/join framework helps you make effective use of current architectures with many cores. It is an implementation of the well known ExecutorService, that uses a work-stealing algorithm to make sure that no worker threads idle by stealing tasks from those that are busy.

It seems fairly easy to use as long as you have a good way of splitting your processing needs into smaller tasks. There is a very handy guide in this tutorial by Oracle.

Dynamism

This does not affect us directly, but it’s a nice addition for the Java Virtual Machine, to which we are seriously tied to.

More and more dynamically typed languages want to leverage the JVM, but they are limited by the fact that the JVM was conceived to be statically typed, which implies that the type information is only checked at compile time, and thus the JVM executes this strongly-typed bytecoded without caring about the type information. This is a limitation for the dynamically typed languages where the type information is unresolved until runtime. A new feature, named invokedynamic, has been introduced in java.lang.invoke, which will allow to create performant, high quality implementations of such languages easier.

Share
 

Don’t look for things. Ask for them!

November 26, 2009 at 12:04 pm | blog, software quality | 3 comments

 

Before our previous article, our code to model a mechanic used to look like this:

class Mechanic {
    private final Engine engine = ServiceLocator.getCar().getEngine();
    public void fixEngine() { /* ... */ }
}

Luckily, we applied some dependency injection, resulting in nicer code: testable, and with an explicit dependency on the ServiceLocator:

class Mechanic {
    private final Engine engine;
    public Mechanic(final ServiceLocator serviceLocator) {
        engine = serviceLocator.getCar().getEngine();
    }
    public void fixEngine() { /* ... */ }
}

However, does our mechanic care about the ServiceLocator at all? Not really, it doesn’t even store a reference to it! The mechanic just wants an engine.

There are some problems with this kind of code:

  • The ServiceLocator probably has references to a lot of other classes in the system. By the transitive property, our Mechanic class is too coupled with the rest of the system: if you want to reuse it in a different project, you’d need to reference not only Mechanic and Engine, but also the ServiceLocator with all its dependencies.
  • The API is not clear. An API client knows that it’d need to provide the ServiceLocator (already an advantage respect to the Singleton-based case). What it doesn’t know is what the mechanic really needs (an engine). This fact is hidden in the source code.
  • The tests contain a lot of setup junk that masks its real purpose. For every test of the mechanic, you’d need to mock the ServiceLocator, and then make sure the appropriate reference can be retrieved from it (the Engine, in this case). When we test the class Garage, that needs a Mechanic, we’ll have to replicate this tedious setup there too.

This is how the test looks like now:

@Test
public void testCantFixBrokenDownEngine() {
    final Engine engine = EngineFactory.buildBrokenEngine();
    final Car mockCark = Mockito.mock(Car.class);
    Mockito.when(mockCar.getEngine()).thenReturn(engine);
    final ServiceLocator mockServiceLocator = Mockito.mock(ServiceLocator.class);
    Mockito.when(mockServiceLocator.getCar()).thenReturn(car);
    final Mechanic mechanic = new Mechanic(mockServiceLocator);
    mechanic.fixEngine();
    assertFalse(engine.works());
}

Why not just ask for what you need?

class Mechanic {
    private final Engine engine;
    public Mechanic(final Engine engine) {
        this.engine = engine;
    }
    public void fixEngine() { /* ... */ }
}
@Test
public void testCantFixBrokenDownEngine() {
  Engine engine = EngineFactory.buildBrokenEngine();
  Mechanic mechanic = new Mechanic(engine);
  mechanic.fixEngine();
  assertFalse(engine.works());
}

Everyone wins:

API writers:

  • Unaffected by ServiceLocator changes
  • In-code documentation is easier to write (what was your comment on the Mechanic‘s constructor for the ServiceLocator)?

Test writers:

  • Tests are easy to read
  • Very little setup code
  • Unaffected by ServiceLocator changes

API users:

  • The API is clear: the mechanic needs an engine
Share
 

Can’t test that Singleton? Try Dependency Injection!

November 11, 2009 at 9:40 pm | blog, software quality | 4 comments

 

So you want to test this method:

public class Client {

    public int process(Params params) {
        final Server server = Server.getInstance();
        final Data data = server.retrieveDate(params);
        // do stuff
    }
}

We don’t want to retrieve an instance of a real server for our little unit-test, so how can we test this method?

It is hard to test code that uses singletons.

We don’t control the creation of the singleton object, as it is performed inside a static method. There is no way to mock the object in order to test the behavior of our method in isolation.

Refactor it to use Dependency Injection.

You can refactor Client to avoid using the singleton pattern. Instead of obtaining the Server instance from the static getInstance() method, allow Client to accept it through its constructor.

public class Client {
    private final Server server;  

    public Client(Server server) {
        this.server = server;
    }  

    public int process(Params params) {
        final Data data = server.retrieveData(params);
        // do stuff
    }
}

Let’s write that test now:

@Test
public void testConnectionUpTime() {
    final Server mockServer = Mockito.mock(Server.class);
    final Params params = // ...
    Mockito.when(mockServer.process(params)).thenReturn(5);
    final Client client = new Client(mockServer);
    assertEquals(5, client.process(params));
}

The code is now both clearer and testable.

The dependency between the client and the server is now explicit: Client client = new Client(server);. There is no way a developer creates a client instance without noticing that a server instance must be configured: it is a parameter in the constructor.

The singleton allowed to create a client instance without configuring the server in advance. The object would be successfully created and the application would execute, until one of the methods runs into a non-configured/non-reachable/null server and fail at runtime :’-(

Share
 

Categories:

Recent posts:

Search:

Subscribe