简体   繁体   中英

How to make a library which uses AutoCloseable and also support Java 6

I'm making a library for Java developers. I would like to make a class that implements the AutoCloseable interface in case the developer uses Java 7. But I also need to provide a version of the class without the AutoCloseable interface for developers targeting Android (which doesn't support AutoCloseable).

The name of my class must be the same in both cases.

One solution is a preprocessor, but I'm targeting developers and can't expect them to adopt any non-standard preprocessor.

So, what is the best practice for supporting two versions of the same class depending on the Java version?

Thanks!

-- Update to clarify:
The ONLY difference in the full source code for the two versions would be the two words "implements AutoCloseable":
public class Transaction { ...
or
public class Transaction implements AutoCloseable {...

  1. Make a backport of AutoCloseable

  2. Make a 2nd Version of your library using the backport instead of the real thing

  3. Either make the user choose which library to use by actually publishing it as two artifacts, or build a common facade which loads the correct version using reflection.

For backporting:

AutoClosable can be reused as is.

For each implementation, you'll need an Adapter to that interface.

The try with resources Statement could look somewhat like

abstract public class Try {
    private List<AutoClosable> closables = new ArrayList<>();

    public void register(AutoClosable closable){
        closables.add(closable); 
    }

    abstract void execute();

    public void do(){
        try{
            execute()
        } finally {
            for (AutoClosable c : closables)
                c.close() // there are tons of exceptionhandling missing here, and the order might need to get reversed ....
        }
    }
}

Usage would look somewhat like:

new Try(){
    File f = new File();
    {
        register(closable(f)) // closabe would return an Adapter from File to AutoClosable
    }

    void execute(){
        f.doSomeFunStuff()
    }
}.do();

You need two versions of your lib, but if you want to have only one source code, take a look at AspectJ , which modifies the byte code after compilation. Thatcway you could get two libs using one sozrce code, but two build targets with different AspectJ options.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM