I'm curious what is considered a better practice when returning a collection of objects from a mutable class:
public class Someclass {
public List<String> strings;
public add(String in){ strings.add(in); }
public remove(String in) { strings.remove(in); }
//THIS
public List<String> getStrings(){
return Collections.unmodifiableList(strings);
}
//OR THIS
public List<String> getStrings(){
return new ArrayList(strings);
}
}
I always assumed wrapping the internal collection in an Unmodifiable was the best approach since I didn't see a reason to incur the overhead of creating a copy. However, it occurred to me that any changes made to the list internally would be exposed to the client which strikes me as bad.
I don't think there is a simple "best practice" answer to this. It really depends on how much of the machine's resources you are willing to spend on preventing violation of the classes data abstraction boundaries. And it depends on what risks you are actually trying to mitigate; e.g. is it simple (non-concurrent) bugs, concurrency bugs, or information leaks.
The options are:
In addition to the direct costs of copying, other performance-related factors are memory usage and garbage generation and the impact on concurrency. For instance, if multiple threads are updating the collection and/or "getting" it, then making a copy of the collection typically involves locking it ... which could potentially make the operation a concurrency bottleneck.
In summary, you need to balance the cost / performance implications against the potential or actual risks and costs of not taking the precautions.
I like to do the latter, but using the .clone()
method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With