3

Had an office query relating to the use of the final construct in Java for HashSet, List, Set, etc.

Say you had a list of usernames, which you wanted to be updated. The list itself won't be reinitialized, just it's values changed.

The question was then raised whether the usernames variable should be a final or not.

private static final List<String> USERNAMES = new List<String>();
...
USERNAMES.add("user1");

Or

private static List<String> usernames = new List<String>();
...
usernames.add("user1");

My question is, which, conventionally, would you use?

The argument can be posed that capitals, implying it's unmodifyable, is not valid here as you can modify the contents of the list (where you can't the list instance itself). Therefore, it's not actually a constant.

By the same token, it's valid to say the list isn't modifyable, therefore capitals & final is fine.

Thoughts? What would the Java conventions say?

I'm genuinely interested in the answer, and believe this is a question. Java conventions must have a stance or comment about this.

Michael
  • 1,014
  • 1
  • 8
  • 23

4 Answers4

2

Declaring it as final may be a good approach. It basically tells you that you are not allowed to changed the reference of the final variable to another instance.

However, be careful with the static. A static variable will make it a class variable meaning that all instances share the same reference. In some cases this may be totally wrong. When you need each instance to have its own instance of usernames, you won't want to make that static.

Dan D.
  • 32,246
  • 5
  • 63
  • 79
  • Thanks for that, I do agree about final. Always safer, if the variable doesn't need to be modified. Re static: That was partly the point, we wanted it to be shared across the classes. It provided a list of usernames (let's say), that the object didn't need to build each time. So the static was fine. Thanks for the pointer though. – Michael Sep 03 '12 at 00:21
1

Capitals are usually used to imply a constant, which is usually a primitive or a string, but sometimes can refer to an object. Rarely in practice do they appear as a basic data structure such as a List. I would say this using capital letters in this case is bad form.

The appropriateness of marking the variable to be final depends on the context, while it is used for constants, this is not the only use. If it's appropriate for the list never to be assigned again, then having a lowercased final e.g.,

private static final List<String> usernames = new List<String>();

would be the best way to go.

dfb
  • 13,133
  • 2
  • 31
  • 52
  • Somewhat agree. Conventions say however, that if you've got a final variable, it should be capitalized. Having it lower isn't entirely correct. However, I do agree that visually, it makes more sense. This is why I posted on the boards :) – Michael Sep 03 '12 at 00:24
-1

When it comes to

final keyword

of Java in the context of Java collections (Maps, Sets and Lists), declaring them as final doesn't make them unmodifyable. When I say collection/container is modifyable/unmodifyable , it actually means that I can/can't modify the contents of it. So using declaring them final actually means that reference to that collection is unmodifyable, but collection by itself is modifyable. Suppose you want to make them unmodifyable, what you have to do is,

UnmodifyableCollection<T> {

  public boolean add(T t){
    throw new  UnsupportedException();
 }

  public T remove(T t){
    throw new  UnsupportedException();
 }

}

something like above where any addition/deletion of contents are not allowed. Collections.unmodifyXXX() methods do the same things.

also final keywords have got wider uses like

1) To Restrict subclassing (making a class immutable)

2) To restrict method overriding

3) To define constants

Also be careful when you declare a collection with static final, because the container is available for all the objects. Check your intent whether you really need that design and be sure why you want that.

sakthisundar
  • 3,278
  • 3
  • 16
  • 29
  • Thanks for your answer, but I was aware that it's modifyable and expressed that. :) It's a question of the appropriateness of final, as it's a final on the reference (in essence). – Michael Sep 03 '12 at 00:23
-1

Marking the list as final won't make the list unmodifiable. Rather, marking it as final only makes it so that it can't be reinitialized.

If you truly want a list that is unmodifiable, I would recommend looking at Guava's ImmutableList.

Here is a snippet from the documentation of an ImmutableList:

Unlike Collections.unmodifiableList(java.util.List), which is a view of a separate collection that can still change, an instance of ImmutableList contains its own private data and will never change. ImmutableList is convenient for public static final lists ("constant lists") and also lets you easily make a "defensive copy" of a list provided to your class by a caller.

alfredaday
  • 2,048
  • 18
  • 14