Home > Net >  Expose `final static Set` of a class
Expose `final static Set` of a class

Time:07-11

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

  1. make IDS private
  2. create a getter method that will return new HashSet<>(IDS) (or ImmutableSet as I'm using Guava)

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.

  • Related