Is there any tricky way to use Java reserved words as variable, method, class, interface, package, or enum constant names?
This is a valid question. Such a thing is possible in other languages. In C#, prefix the identifier with # (as asked before); in Delphi, prefix with &. But Java offers no such feature (partly because it doesn't really need to interact with identifiers defined by other languages the way the .Net world does).
No, there is no way. That's why they're labeled "reserved".
Most often this issue comes up for "class", in this case it is customary to write "clazz".
Strictly speaking you can't, unless you get your hands on a buggy compiler implementation that doesn't adhere to the Java language spec.
But where there's a will, there's a way. Copy the following code into your IDE, switch the source file encoding to UTF-16 and here we go:
public class HelloWorld {
public static void main(String[] args) {
HelloWorld.nеw();
}
public static void nеw () {
System.out.println("Hello,World");
}
}
This code is a well-formed and valid Java class. However, as you have guessed there is a little trick: the 'е' character within "new" identifier does not belong to the ASCII character set, it is actually a cyrrilic 'е' (prounanced 'YE').
Current Java language spec explicitly permits, and this an important point to make, the use of Unicode for naming identifiers. That means that one has an ability to freely call her or his classes in French, Chinise or Russian if they wish. It is also possible to mix and match the alphabets within code. And historically, some letters within Latin and other alphabets are lookalikes.
As a result: no, you can't use the reserved words as identifiers, but you can use identifiers that look exactly like reserved words.
Whether anyone should be doing it is a totally different matter.
No, you can't do this. For more information please go to JLS Sections 3.8, 3.9
The following character sequences,
formed from ASCII letters, are
reserved for use as keywords and
cannot be used as identifiers (§3.8):
Keyword: one of
abstract continue for new switch
assert default if package synchronized
boolean do goto private this
break double implements protected throw
byte else import public throws
case enum instanceof return transient
catch extends int short try
char final interface static void
class finally long strictfp volatile
const float native super while
Yes, there is.
You have to use reserved words from the future.
Like what happened with different methods called assert() in pre-1.4 code.
Hope it helps!
In Scala you can use backticks. For example: myVarialbe.`class`
Not sure what you're trying to do, but $ is a valid character in identifiers, so you could do, say:
int $return = 5;
It looks a little weird, but it does work.
I know it's old question still, might help someone.
It's possible by using GSON's Field Naming Support
eg.
#SerializedName("new")
private String New;
public String getNew ()
{
return New;
}
public void setNew (String aNew)
{
New = aNew;
}
Huh? Why would you want to do that? You can write them in l33t, that will fool the compiler.
class cl4ss {
String r3turn() {
return "but why?";
}
}
There is no way to use reserved words with the javac compiler.
Technically, you can edit the names inside the class file once it's compiled to be anything you want: at that stage, the VM doesn't care, because it's not dealing with source code any more. I believe some obfuscators use this technique.
PL/1 (a 1960's IBM mainframe programming language still around today) rather famously required that while some words act like keywords in certain contexts, all words can be used as identifiers. This isn't even that hard to do in a parser if you set out to be consistent about it. PL/1 was considered to a rather big langauge, and the langauge committee worried that many programmers wouldn't learn all of it, and then would get suprised when they tried to use the keyword from a part they didn't know as an identifier.
So you could write things like:
IF BEGIN=ELSE THEN CALL=3 ELSE CALL FOO(ENDIF) ENDIF
As others have noted here, the ability to do this isn't a recommendation.
The Java designers decided the number of keywords in the langauge was modest, and reserved the set. They even reserved 'GOTO', which isn't actually allowed in any real Java program.
If you really need to use a field/local variable/method named the same as a reserved word, I suggest appending an underscore at the end of the name:
// JPA entity mapping class:
private Boolean void_;
public Boolean getVoid_() { ... }
void setVoid_(Boolean void_) { ... }
It is a more readable choice (IMHO) than appending chars at the beginning of the name (fVoid, aVoid, vVoid, etc.)
The code above is a real world case that happened to me, working with a legacy database, in which the invoice table had a field named void indicating whether the document had been voided or not.
Related
if I have the following private member:
private int xIndex;
How should I name my getter/setter:
getXindex()
setXindex(int value)
or
getxIndex()
setxIndex(int value)
EDIT: or
getXIndex()
setXIndex(int value);
?
The correct answer is
getxIndex()
setxIndex(int value)
if you want them to be used as properties according to section 8.8: Capitalization of inferred names of the JavaBeans API specification (e.g. access them via ${object.xIndex} in a JSP.
In accordance with JavaBeans API specification from 1997
it should be as Thomas Einwaller describes:
// According to JavaBeans API specification
public int getxIndex() { return xIndex; }
public void setxIndex(int xIndex) { this.xIndex = xIndex; }
This is unfortunate, getx and setx are not words. In the rare case when this would form a word or acronym it would be disinformative, eg the method setiMessage most
likely has nothing to do with SETI.
Using the only valid measurement of code quality (WTFs per minute),
I assess that this is bad code.
If we modify this to follow the convention for
naming a method it would be:
// According to Java naming convention
public int getXIndex() { return xIndex; }
public void setXIndex(int xIndex) { this.xIndex = xIndex; }
Why does the JavaBeans specification violate the convention? It all comes down to this sentence of the JavaBeans specification:
However to support the occasional use of all upper-case names, we check if the first two characters of the name are
both upper case and if so leave it alone.
Exactly what kind of use of all upper-case names this refers to is unclear to me. Field names should, according to
convention, be camel cased. It seems
to me that we generate unconventional method names in order to support unconventional field names as decided by a
20+ year old document.
It should also be noted that even though it seems to be an overwhelming support for the JavaBeans specification in tools,
it is not exclusively used. Eg. Kotlin will not recognize xIndex as a property in the above example. Reversely, the
Kotlin property var xIndex = 0 will result in the Java methods getXIndex and setXIndex. This seems to be a bug
according to the JetBrains support, but I fail to see how they can fix that without making a breaking change.
Some tools that does support the JavaBeans specification has not always done so, eg Jackson
and Swagger Code Generator have been patched to conform to it.
Even though IntelliJ generate accessors according to the JavaBeans specification, the example
in the documentation differs from it. Probably because people don't know about the standard and naturally prefers the
normal method naming convention.
So when should we follow the JavaBeans specification? When property names should be inferred by accessors by tools that
rely on this standard, then we might want to use it. For instance, Jackson will rely
on the property xIndex being accessed through getxIndex and setxIndex methods unless we use annotations.
When should we avoid this standard? Per my recommendation: When the code should be read and understood by humans.
Because to not use proper camel casing when naming methods is disinformative.
If I would have it my way, we would use normal naming conventions, ie getXIndex and setXIndex. But, given the state
of things, the best solution I see is suggested by #vaxquis:
Name your field "indexX" or whatever else, your problem is solved... don't overcomplicate things - even if setxIndex
is the correct way for Beans, having method named setxIndex increases the WTF factor of the code without giving you
anything in return.
Any comments regarding the JavaBeans specification should, according the specification itself, be sent to
java-beans#java.sun.com.
Should be:
getXIndex()
setXIndex(final int xIndex)
Methods should be verbs, in mixed case with the first letter lowercase, with the first letter of each internal word capitalized.
You should use Introspector.decapitalize from package java.beans and you have no problem beacause it is compliant with java rules.
Eclipse ide automatically generates setters and getters as:
getxIndex()
setxIndex(int value)
Which is according to the java beans API specification.
I think getXindex() is the best way. The getter should start with 'get', followed by the member name, with its first letter capitalized. Also the latest conventions I heard of, say that we should avoid multiple capital letters one after another. For example getHTMLtooltip is wrong. it should be getHtmlTooltip instead. Also you should try to make all your members final and there should not be a need of setters, since the class will be immutable ;)
A new Code Review process has been put in place and now my team must not ever declare a string as a local variable, or the commit won't pass the code review. We are now to use constants instead.
So this is absolutely not allowed, even if we're dead sure the string will never be used in any other place
String operationId = "create";
This is what should be used instead:
private static final String OPERATION_ID = "create";
While I totally agree to use constants for strings that appears +2 times in the code ... I just find it overkill to completely not have the ability to declare a string in place if it's used only once.
Just to make sure it's clear, all the following are NOT ALLOWED under any circumstances:
String div = "div1";
Catch(Exception ex){ LOGGER.log("csv file is corrupt") }
String concatenation String str = "something ...." + someVar + "something" ... we are to replace someVar with %s, declare whole thing as a global string, and then later use String.format(....)
if( name.equals("Audi" ){....}
String value = map.get("key")
Any ideas guys ? I want some strong arguments. I'm ready to embrace any stand that's backed by a good argument.
Thanks.
First, let's throw out your assumption: There's nothing inherently wrong with the approach described.
It's not about strings being used in more than one place, it's about constants being easy to find and documented, and your code being consistent.
private static final String OPERATION_ID = "create";
Really, this isn't used anywhere else? Nothing would break if I changed this to the string "beetlejuice"? If something would break, then something else is using this constant... If the "something else" happens to be a codebase in a different language, and that's why they don't share string constants-- that's the exception, not the rule. Consistency!
That said, there are a few things I would standardize in a slightly different manner, but I would still standardize them nonetheless:
I would suggest allowing string literals in the constructors of enums:
public enum Operation {
CREATE("create"),
...
}
because here, the enum is the constant that is being referenced in the code, not the string literal. Declaring the constant as an enum or as a private static final String are equivalent to me, and there's no need to do both.
Additionally, I would not use this pattern anywhere that it breaks your IDE's ability to warn you about missing strings-- For example, looking up strings from .properties files. Many IDEs will give you proper warnings when you look up a key in a .properties file that doesn't exist, but the extra level of indirection might break that depending upon how smart your IDE is.
Catch(Exception ex){ LOGGER.log("csv file is corrupt") }
This to me is a bit of a gray area - Is this an internal-only message? Are the logs only ever seen by you, the developer, or are they for a user's benefit too?
If it's only for developers of the application These probably don't need to be localized.
If you do expect the user to view the logs, then they should be externalized into a .properties file.
It is good coding style to define a constant for a value/literal when the value/literal is used multiple times.
The imposed coding style forces you to use a constant for every string literal.
The good effect of that coding style is: All string literals which really should be declared as constants are now declared as constants.
The bad implication of that coding style is: You - the developers - are not able to decide if a string literal should be defined as constant or not. This is a heavy punch.
Therefore you should raise your concerns that the good intention of the coding style does not compensate for the mistrust in your developer qualitites.
I would like to know what the overall recommendation is for whitespace between a method's name and its parameters.
That is, the general preference between the following two lines:
public static void main (String[] args) {} // (We'll ignore the question of spaces between the `String` and `[]` .)
public static void main(String[] args) {}
I recently have begun to feel like the former is the better one, especially considering that everything else in a method declaration (e.g. the throws Exception(s) section) is also space-separated.
As #chris mentioned in the comments, the Official Java Code Conventions specifically states:
Note that a blank space should not be used between a method name and its opening parenthesis. This helps to distinguish keywords from method calls.
As you questionably considered in your question, methods are different on purpose.
2018 update: since almost all IDEs allow easy invocation/declaration lookup, the main gains of switching the convention here are moot; after 3 years, I've switched back to "no space after method name" rule just because most style guides in most languages use it... making an exception to existing code styles is IMVHO viable when the gains outweigh the "WTF factor" of the change; in this case, with up-to-date tooling, there are no actual gains, so I'd personally recomend against the alternative proposed below.
I beg to differ with the interpretation of 1999's unmaintained White Space Java conventions. It only says that the space shouldn't be used to help distinguish keywords from method calls. Thus, there ain't no official rules as to whether use the space in contexts where method call can't appear (and thus where no such help is needed) - as such, the rule obviously does apply to invocative context (where calls can appear and where it helps) and doesn't apply to declarative context (where calls can't appear and where it would serve no purpose). Even more - because the conventions state that the whitespace use should help in distinguishing the usage context, using space on declaration actually keeps with the spirit of the rule - it actually allows you to distinguish method invocation from method declaration, even when using simple text search (just search for the method name followed by space).
After switching to it, distinguishing invocations from the declaration got easier. It also highlighted the fact that the parentheses after the name ain't the invocative ones - and that their syntax is different from the call syntax (i.e. type declarations are needed before variable names etc.), as you noticed already.
tl;dr you can use
void method () { } // declaration
void method2 () { // declaration
method(); // invocation
}
to be able to quickly do searches on declarations/invocations only and to satisfy the convention at the same time.
Note that all the official Java code, as well as most of the code styles in the wild, doesn't use the space in the declarations.
I'm trying to create a kind of "shorthand" syntax for Java that replaces verbose keywords with less verbose ones, so that I can write Java code with fewer keystrokes. Is there any way to replace keywords such as "public" and "static" with abbreviations of those keywords, and then translate that to "normal" Java code?
//would it be possible to convert this to "normal" Java code?
pu cl ModifiedSyntaxExample{
pu st void main(){
System.out.println("Hello World!")
}
}
This would be equivalent to:
//would it be possible to convert this to "normal" Java code?
public class ModifiedSyntaxExample{
public static void main(){
System.out.println("Hello World!")
}
}
The first version is less verbose (and therefore easier to type), because "public" and "class" are replaced with the abbreviations "pu" and "st".
If you are using any IDE than yes, its possible. For example in eclipse you have one code snippets which you can configure in such a way that, you will make your code less verbose. I hope I have understood your question correctly.
for ex - sysout will print System.out.println(); for you.
Is there any tricky way to use Java reserved words as variable, method, class, interface, package, or enum constant names?
This is a valid question. Such a thing is possible in other languages. In C#, prefix the identifier with # (as asked before); in Delphi, prefix with &. But Java offers no such feature (partly because it doesn't really need to interact with identifiers defined by other languages the way the .Net world does).
No, there is no way. That's why they're labeled "reserved".
Most often this issue comes up for "class", in this case it is customary to write "clazz".
Strictly speaking you can't, unless you get your hands on a buggy compiler implementation that doesn't adhere to the Java language spec.
But where there's a will, there's a way. Copy the following code into your IDE, switch the source file encoding to UTF-16 and here we go:
public class HelloWorld {
public static void main(String[] args) {
HelloWorld.nеw();
}
public static void nеw () {
System.out.println("Hello,World");
}
}
This code is a well-formed and valid Java class. However, as you have guessed there is a little trick: the 'е' character within "new" identifier does not belong to the ASCII character set, it is actually a cyrrilic 'е' (prounanced 'YE').
Current Java language spec explicitly permits, and this an important point to make, the use of Unicode for naming identifiers. That means that one has an ability to freely call her or his classes in French, Chinise or Russian if they wish. It is also possible to mix and match the alphabets within code. And historically, some letters within Latin and other alphabets are lookalikes.
As a result: no, you can't use the reserved words as identifiers, but you can use identifiers that look exactly like reserved words.
Whether anyone should be doing it is a totally different matter.
No, you can't do this. For more information please go to JLS Sections 3.8, 3.9
The following character sequences,
formed from ASCII letters, are
reserved for use as keywords and
cannot be used as identifiers (§3.8):
Keyword: one of
abstract continue for new switch
assert default if package synchronized
boolean do goto private this
break double implements protected throw
byte else import public throws
case enum instanceof return transient
catch extends int short try
char final interface static void
class finally long strictfp volatile
const float native super while
Yes, there is.
You have to use reserved words from the future.
Like what happened with different methods called assert() in pre-1.4 code.
Hope it helps!
In Scala you can use backticks. For example: myVarialbe.`class`
Not sure what you're trying to do, but $ is a valid character in identifiers, so you could do, say:
int $return = 5;
It looks a little weird, but it does work.
I know it's old question still, might help someone.
It's possible by using GSON's Field Naming Support
eg.
#SerializedName("new")
private String New;
public String getNew ()
{
return New;
}
public void setNew (String aNew)
{
New = aNew;
}
Huh? Why would you want to do that? You can write them in l33t, that will fool the compiler.
class cl4ss {
String r3turn() {
return "but why?";
}
}
There is no way to use reserved words with the javac compiler.
Technically, you can edit the names inside the class file once it's compiled to be anything you want: at that stage, the VM doesn't care, because it's not dealing with source code any more. I believe some obfuscators use this technique.
PL/1 (a 1960's IBM mainframe programming language still around today) rather famously required that while some words act like keywords in certain contexts, all words can be used as identifiers. This isn't even that hard to do in a parser if you set out to be consistent about it. PL/1 was considered to a rather big langauge, and the langauge committee worried that many programmers wouldn't learn all of it, and then would get suprised when they tried to use the keyword from a part they didn't know as an identifier.
So you could write things like:
IF BEGIN=ELSE THEN CALL=3 ELSE CALL FOO(ENDIF) ENDIF
As others have noted here, the ability to do this isn't a recommendation.
The Java designers decided the number of keywords in the langauge was modest, and reserved the set. They even reserved 'GOTO', which isn't actually allowed in any real Java program.
If you really need to use a field/local variable/method named the same as a reserved word, I suggest appending an underscore at the end of the name:
// JPA entity mapping class:
private Boolean void_;
public Boolean getVoid_() { ... }
void setVoid_(Boolean void_) { ... }
It is a more readable choice (IMHO) than appending chars at the beginning of the name (fVoid, aVoid, vVoid, etc.)
The code above is a real world case that happened to me, working with a legacy database, in which the invoice table had a field named void indicating whether the document had been voided or not.