ConventionProperty can be assigned but cannot be mutated (even if the object is mutable!)
Understanding convention properties is important mostly for collections because one might want to mutate the collection but it wouldn't work (actually mutating may work but it will be sensitive to the evaluation order).
Consider this example:
someTask { //Convention properties cannot be mutated, //even if the object is mutable! conventionProperty.add('c') //WRONG! //However, convention properties can be assigned: conventionProperty = ['a', 'b'] //OK //Following may work but depends on the order of evaluation: conventionProperty -= 'a' //SENSITIVE //Simple properties can be mutated or assigned: simpleProperty = ['1.5'] //OK simpleProperty.add('1.5') //OK }You may wonder why Gradle uses convention properties. The reason for that is that internally, convention properties are evaluated 'lazily'. This means that Gradle can configure tasks and objects with reasonable defaults without worrying about the order of statements that configure the build. Example:
apply plugin: 'java' test { //test task has a testClassesDir convention property //that is by default configured to 'test classes dir' //testClassesDir = sourceSets.test.classesDir } //what if someone reconfigured the 'test classes dir' //after the 'test' task was configured? Like that: sourceSets.test.classesDir = new File(buildDir, 'test-classes') //will the already-configured test.testClassesDir property //on a 'test' task point to a wrong folder?Answer: It will all work fine!
Thanks to the 'lazy' evaluation of the convention properties the user can reconfigure the sourceSets anywhere in the gradle script - and still the test.testClassesDir will point to the right folder.