Defer in Logo

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;

public class Defer {

    public static void main(String[] args) {
        // In Java, we use try-with-resources to automatically close resources
        // This is similar to the defer concept in Go
        try (FileWriter fileWriter = createFile("/tmp/defer.txt");
             BufferedWriter bufferedWriter = new BufferedWriter(fileWriter)) {
            
            writeFile(bufferedWriter);
        } catch (IOException e) {
            System.err.println("Error: " + e.getMessage());
            System.exit(1);
        }
    }

    private static FileWriter createFile(String path) throws IOException {
        System.out.println("creating");
        return new FileWriter(path);
    }

    private static void writeFile(BufferedWriter writer) throws IOException {
        System.out.println("writing");
        writer.write("data");
        writer.newLine();
    }
}

In Java, we don’t have a direct equivalent of the defer keyword. However, we can achieve similar functionality using the try-with-resources statement, which was introduced in Java 7.

The try-with-resources statement ensures that each resource is closed at the end of the statement. It’s a more concise and safer way to handle resources that need to be closed after we’re done using them.

In this example:

  1. We create a FileWriter and a BufferedWriter in the try-with-resources statement. These will be automatically closed when the try block exits, similar to how defer works in Go.

  2. The createFile method creates a new FileWriter. If there’s an error, it will throw an IOException which is caught in the main method.

  3. The writeFile method writes to the file using the BufferedWriter.

  4. Any IOException that occurs during file operations is caught in the main method, where we print the error and exit the program.

To run the program:

$ javac Defer.java
$ java Defer
creating
writing

The output confirms that the file is created and written to. The file is automatically closed when the try-with-resources block ends, even if an exception occurs.

This approach provides similar benefits to Go’s defer:

  • It ensures that resources are properly closed, even if an exception occurs.
  • The resource closing is specified at the beginning of the block, making the code easier to read and understand.
  • It reduces the risk of resource leaks by automating the closing process.

While the syntax is different from Go, the concept of ensuring cleanup operations are performed is maintained in this Java equivalent.