Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Groovy @Immutable class with (im)mutable property

I'm trying to use Groovy @groovy.transform.Immutable to implement classes with properties of unsupported "immutable" types. In my case it is java.io.File

For example, having class like

@groovy.transform.Immutable class TwoFiles {
    File file1,file2
}

gives me following compile error

Groovyc: @Immutable processor doesn't know how to handle field 'file1' of type 'java.io.File' while compiling class TwoFiles. @Immutable classes only support properties with effectively immutable types including: - Strings, primitive types, wrapper types, BigInteger and BigDecimal, enums - other @Immutable classes and known immutables (java.awt.Color, java.net.URI) - Cloneable classes, collections, maps and arrays, and other classes with special handling (java.util.Date) Other restrictions apply, please see the groovydoc for @Immutable for further details

One option I found it to extend java.io.File to make it Cloneable but I'm not happy with this solution. Following code compiles and works, but having own subclass of java.io.File is not what I'd like.

@groovy.transform.Immutable class TwoCloneableFiles {
    FileCloneable file1,file2

    class FileCloneable extends File implements Cloneable{

        FileCloneable(String s) {
            super(s)
        }

        // ... and other constructors ...
    }
}

So my question is: Is there any other option how to use java.io.File directly in such class?

Possibly to mark java.io.File as "known immutable" for the purpose of @groovy.transform.Immutable (same as it seems to be done for java.awt.Color, java.net.URI)?

like image 338
Arnost Valicek Avatar asked Jan 06 '13 19:01

Arnost Valicek


1 Answers

Have you tried using knownImmutableClasses to specify File? Something like this should work:

@groovy.transform.Immutable(knownImmutableClasses = [File])
class TwoFiles {
    File file1,file2
}

(With File, you could probably also get rougly the effect you want with the following:

@groovy.transform.Immutable
class TwoFiles {
    String file1,file2
    public File getFile1() {return new File(file1)}        
    public File getFile2() {return new File(file2)}        
}

def f = new TwoFiles("/", "/Users")
assert f.file1.class == File

)

like image 116
Brian Henry Avatar answered Sep 28 '22 07:09

Brian Henry