Java reserved keywords.
Programming languages have always reserved keywords, that cannot be used in a particular context. Wanna write «String class = “I can do anything!”»? You can write that, but the program won’t compile, ‘cause the class keyword is used to declare a class and you can’t use it as a variable name.
Below is a scheme of reserved keywords in Java. Are all the words familiar to you?
Who used strictfp? And pure assert without JUnit? Are there any fans of (‘perversions’) the abbreviations of variable names to «_»?
There are 65 reserved keywords in JDK 12 in total. The specification says, that literals and var are not exactly keywords, but still they can be attributed to them.
Unused keywords — (‘useless’) meaningless, but at the same time reserved keywords. It is necessary that negligent developers do not create confusion for both man and machine, if they suddenly want to name a variable or class this word.
Here’s an excerpt from the specification:
«The keywords const and goto are reserved, even though they are not currently used. This may allow a Java compiler to produce better error messages if these C++ keywords incorrectly appear in programs.»
Restricted keywords — these words came to us with the JDK 9 modular system. Yes, they can easily be used as names of variables or classes, they are reserved only in module descriptions. This is done for backward compatibility with previously written programs for the sake of fans of «obvious» variable names.
exports — indicates that a code in a particular package is available for use by a code in other modules.
module — used to declare a module.
open — indicates that all packages in a module are available for use by a code in other packages.
opens — gets access to the entire code in other module via reflection.
provides — provides access to the service interface.
requires — specifies the dependency of the current module on another module (service).
to — indicates a code that has permission to use a specific piece of code.
transitive — transitive dependency, denotes that if module A requires module B, module B will be granted access to module A automatically.
uses — indicates that the module uses the service interface.
with — defines the implementation of the provided service interface.
Type name — restricted local variable type, a special, looong-awaited by many word var, that can’t be used as a class name, cause it is reserved for «dynamic» typing. In quotes, cause the type is actually substituted during compilation. But the variable name var can easily be:
From the same specification:
«var is not a keyword, but rather an identifier with special meaning as the type of a local variable declaration and the type of a lambda formal parameter.»
Used keywords — these reserved keywords are actively used and their use as a variable or class name is unacceptable.
By the way, the names in Java are case-sensitive, so the following spelling is allowed:
Literals: true & false are rather Boolean-literals and null is rather the null-literal than keywords, but we still love them and use them only for their intended purpose.
Other: “_” (underscore) — before Java 9 the use of underscore as names was legal (though immoral). But with the advent of JEP 302 everything changed and soon the underscore became a keyword (or rather a key-symbol?).
« In many languages, it is common to use an underscore (_) to denote an unnamed lambda parameter (and similarly for method and exception parameters):
BiFunction<Integer, String, String> biss = (i, _) -> String.valueOf(i);
This allows stronger static checking of unused arguments, and also allows multiple arguments to be marked as unused.»
Let me give a description of some of the most interesting or rare (yeah, yeah, that’s you strictfp) keywords:
Get Alex Kuk’s stories in your inbox
Join Medium for free to get updates from this writer.
void — this is not just an indication that the method doesn’t return any value. ‘void’ — is the return type. That is, methods marked ‘void’ actually return type ‘void’. void itself is defined as an incomplete type and can’t be used instead of its complete counterparts, for example, as a function parameter type.
And then there’s the Void class, but that’s absolutely another story.
In order not to produce new keywords often use already existing more or less relevant. In example of this — are generics. With their appearance it is decided to use two already existing words extends and super. Previously, they only meant extending the class/interface and referring to the parent class, respectively. Now, when framing these words in <>, the compiler processes this as refer to generics. For example:
the opapa collection has Object-type elements or its supertypes (higher — parents, grandparents, etc.), and the collection opapa2 has Object-type elements or extending its types-classes (lower — heirs).
An inquisitive reader has already noticed that the records provided in the example carry a wagon and a small cart of deep meaningfulness, alien to ordinary coders. Right, Object — is «God» among classes, there can be no one above God, and absolutely all servants are below God (what the IDE hints at). Therefore, the meaning of such records will remain behind the scenes and in the minds of a certain circle of persons.
assert — the word has appeared since Java 1.4 and by default its use is equal to its non-use. To make it work, you need to enable the JVM «-ea» option. The word itself is a test of the expression:
and in case of a false result, it throws an exception:
native — indicates that the method body is not written in divine Java, but in some other non-progressive language (C, B, pluses, minuses, grids, etc.). At the same time, we can invoke this method from Java and get the result. It is often used by lazy programmers for working with an already existing external component, instead of writing their own, or to access specific features of the OS. JDK example:
synchronized — synchronizing a method or block between threads, i.e. one thread went inside and does its job, while the rest suffer on the outside.
volatile — take the value of a variable each time from shared memory, instead of the local processor cache. What for? That’s when you read on the wiki a scientific article, that struck you to the core, five years ago about the fact that the Earth is flat, i.e. it was pulled into the Black Hole and flattened under the influence of strong gravity, then you still tell it unchanged form from memory to your friends, though the results of studies a week after the release were refuted, and the article was updated. In this case, volatile would force you to re-read the article on wiki before each story to your friends.
transient — disregard a particular variable during serialization: neither save nor restore it, in general, ignore to the maximum.
strictfp — strict floating-point. On different platforms hardware can provide different precision in calculations, and prior to Java 1.2 all intermediate results of calculations were automatically brought in line with IEEE 754 standards for single (float) or double precision to avoid arithmetic overflow or underflow. But since Java 1.2 intermediate results by default can exceed standard ranges and give the maximum possible precision, which is useful in aviation or science. Thus, if you do not want precision, but portability between platforms, or your customer twitches from scary words overflow & underflow, boldly put the word strictfp in front of the class / interface / method, then all floating-point calculations inside such methods will be restricted and reduced to the IEEE standard.
Conclusion:
Over time, new keywords are added to Java, and no one is immune from the fact that your variable names in the future version will be illegal. But JDK developers always try to make maximum compatibility with previously written programs, and therefore, for example, when entering new keywords, they limit the scope of their use, or suggest using compound expressions, that developers could not use as variable names before due to hyphenation. Here are some keywords that could potentially appear in the future:
- `non-null`
- `non-final`
- `package-private` (the default accessibility for class members, currently not denotable)
- `public-read` (publicly readable, privately writable)
- `null-checked`
- `type-static` ((a concept needed in Valhalla, which is static relative to a particular specialization of a class, rather than the class itself)
- `default-value`
- `eventually-final` (what the `@Stable` annotation currently suggests)
- `semi-final` (an alternative to `sealed`)
- `exhaustive-switch` (opting into exhaustiveness checking for statement switches, i.e. whether all possible values in the switch statement have been listed)
- `enum-class`, `annotation-class`, `record-class` (we might have chosen these as an alternative to `enum` and `@interface`, had we had the option)
- `this-class` (to describe the class literal for the current class)
- `this-return` (a common request is a way to mark a setter or builder method as returning its receiver)
And what keywords would you like to add to the language?
Tricky question: will almighty reflection cope with substitution goto as a variable name? And as a class name?







