We all have various constants in our code, whether they are integers for use
startActivityForResult(), strings for Logcat tags, and so forth. Most
of these are internal to our code and do not affect others.
Sometimes, though, we have an API that we expose that others might call, where
certain parameters are up to the caller… except for some magic constants. For
example, you might have a key/value data store, where you want to reserve some
keys for your internal use, but others can stuff whatever they want into that data
store using their own choices of keys. Those reserved keys are magic constants.
(IMHO, try to avoid such APIs, keeping your internal data separate so there
is no chance of a key collision… but sometimes this API structure is unavoidable)
So, the caller of your API can choose any value for their keys, except certain
magic constants. In that case:
Practice defensive programming and validate that a caller-supplied key is
not one of your magic constants,
Document what the magic constants are, and
Choose obscure values
When it comes to
NotificationChannel, we got two out of the three.
NotificationChannel has a
DEFAULT_CHANNEL_ID constant. This is a magic constant,
as you cannot use it as the ID of your own channel. If you try,
you get a somewhat cryptic stack trace.
But, that stack trace is because of the defensive programming, so that’s good.
And the magic constant is documented, at least to an extent.
However, the value of
That’s a reasonably common English word, one that somebody might well choose
without noticing that it is not an eligible value.
Particularly with strings, you have a near-infinite space to choose magic constants
from. So, it is easy to choose a magic constant that is unlikely to collide with
any value that others might choose:
Even if memory use is a consideration, it would be better to choose a random
six-digit number than to use a common word. There are lots of obscure values
that we could use that are shorter than
After all, neither the compiler nor the OS really cares about the actual value.
Your own code does not care about the individual characters inside of the magic
constant. It just needs to know that it can look up things using that magic constant
and get what it expects.
Magic constants are part of your API and they need to be designed along with the
rest of the API. It’s just that whereas normally you want things to be human-readable,
this is one case where you do not. Or, at the very least, choose a less-common
human-readable word, such as
(NOTE: no actual axolotls were harmed in the creation of this blog post)