permaculture playing cards
The moose likes Beginning Java and the fly likes Strings are poor substitutes for capabilities Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Strings are poor substitutes for capabilities" Watch "Strings are poor substitutes for capabilities" New topic

Strings are poor substitutes for capabilities

Cairo Jackson

Joined: Jan 18, 2007
Posts: 14
I am reading the book Effective Java, written by Joshua Bloch. Now, I'm with Item 32: Avoid strings where other types are more appropriate.

I can't understand the last point: Strings are poor substitutes for capabilities. I copied the part that I dun understand:

Occasionally, strings are used to grant access to some functionality. For example, consider the design of a thread-local variable facility. Such a facility provides variables for which each thread has its own value. When confronted with designing such a facility several years ago, several people independently came up with the same design in which client-provided string keys grant access to the contents of a threadlocal variable:

The problem with this approach is that the keys represent a shared global namespace. If two independent clients of the package decide to use the same name for their thread-local variable, they unintentionally share the variable, which will generally cause both clients to fail. Also, the security is poor; a malicious client could intentionally use the same key as another client to gain illicit access to the other client's data. This API can be fixed by replacing the string with an unforgeable key (sometimes called a capability):

While this solves both of the problems with the string-based API, you can do better. You don't really need the static methods any more. They can instead become instance methods on the key, at which point the key is no longer a key: it is a thread-local variable. At this point, the noninstantiable top-level class isn't doing anything for you any more, so you might as well get rid of it and rename the nested class to ThreadLocal:

This is, roughly speaking, the API that java.util.ThreadLocal provides. In addition to solving the problems with the string-based API, it's faster and more elegant than either of the key-based APIs.

I really dun understand what he wants to say, especially with the ThreadLocal sample. Can any one tell me what does "Strings are poor substitutes for capabilities" actually mean? in any easier sample codes?

Thank you very much.
David O'Meara

Joined: Mar 06, 2001
Posts: 13459

Forget ThreadLocal for now, if you haven't already used them it will just confuse the matter.

Imagine you have a nasty caching mechanism that is maintained globally and uses String values as keys for the data. (don't laugh, I've seen things that were conceptually the same) You give data a name, put in the cache, then pull it out by name.

Now you only have a single namespace: that is, all Strings you keep get stored in the same pool in the names of cached objects. If you read and write two objects called "mydata" from different locations in your application, they will collide and interfere with each other.

Here the capability we're looking for is the unique keying of cached data. Strings look like a good fit and are easy to use, but they don't actually provide the capabilities required.
Anupam Sinha
Ranch Hand

Joined: Apr 13, 2003
Posts: 1090

I am also reading the same book. Now I am also at the same item. Can you please throw some more light into it. specially considering the fact that thread local would be in any case local to a thread how come can there be a key collision?
David O'Meara

Joined: Mar 06, 2001
Posts: 13459

because it doesn't specify where the name is valid during the execution of the Thread. If multiple sections set/get the ThreadLocal String value, there is no implicit mechanism to protect this namespace collision. If you want a locking or key mechanism, do so, but be wary of using Strings as they are a poor substitute for the real functionality.
I agree. Here's the link:
subject: Strings are poor substitutes for capabilities
It's not a secret anymore!