I have a class that has:
public static final Set<String> IDS = new HashSet<>();
,
whose values are initiated in a static block after running some query (Therefore I can't declare it as unmodifiableSet
).
Now that other classes need to use IDS
but apparently I don't want to let them get direct access to it to avoid IDS
being changed by callers.
To achieve this, one way I can think of, is to
- make
IDS
private - create a getter method that will
return new HashSet<>(IDS)
(orImmutableSet
as I'm usingGuava
)
But wondering if there are better ways?
CodePudding user response:
Try this.
public static final Set<String> IDS;
static {
Set<String> set = new HashSet<>();
set.add("a");
set.add("b");
set.add("c");
IDS = Collections.unmodifiableSet(set);
}
public static void main(String[] args) {
System.out.println(IDS);
IDS.add("x");
}
output:
[a, b, c]
Exception in thread "main" java.lang.UnsupportedOperationException
CodePudding user response:
You could use a temporary Set in your static block
public static final Set<String> IDS;
static {
final Set<String> temp = new HashSet<>();
// Run your query and add ids to temp
IDS = Collections.unmodifiableSet(temp);
}
CodePudding user response:
If you want to expose a set (or any other collection) from your class, you could use java.util.Collections#unmodifiableSet
. It is very lightweight, because it just wraps your set and proxies all non-modifying calls to the underlying set.
And keep the state hidden. One class should at most expose constants, better add a getter for the collection.