Reserved words as names or identifiers
Asked Answered
B

13

30

Is there any tricky way to use Java reserved words as variable, method, class, interface, package, or enum constant names?

Byelorussian answered 8/1, 2009 at 11:47 Comment(2)
It's not so strange, that he want do that. That's why C# has @ prefix, and Delphi has & and variable or method named eg. @if is legal in C#.Tufthunter
I don't get all the "don't do it" comments. It is perfectly legitimate to call APIs from Java that weren't themselves written in Java, and there are identifiers which are perfectly legal in JVM byte code which aren't legal in Java. That's precisely why languages like C# (@class), Scala (`class`) and others have escaping mechanisms. There are 500 languages on the JVM, if I tried to take every single reserved word from every single one of those 500 languages into account when designing APIs, I'd go insane (and someone might invent a new language with a new reserved word later anyway).Tatiania
G
31

No, there is no way. That's why they're labeled "reserved".

Gershom answered 8/1, 2009 at 11:49 Comment(3)
Adding a " _ " in front of a reserved keyword like "_new" is the closest thing you'll get.Hutch
@Hutch _ is not allowed everywhere in vrabiel names, for example not in lambda parametersCobalt
@Cobalt You are wrong.Autohypnosis
R
45

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).

Repentance answered 8/1, 2009 at 12:48 Comment(4)
Well, if you are willing to accept the C# hack, you can prefix Java names with ZZZ or any other character sequence that you won't otherwise use as a prefix.Harebrained
But Ira, that changes the identifier. The C# and Delphi ways escape the original name, but it's still the same name. In Delphi, you can even write the fully qualified name without the escape character.Repentance
This becomes especially visible in Xml or JSON serialization as the serialized text would have ZZZ as part of the tag name <ZZZstring></ZZZstring>, whereas in C#, @string would serialize to <string></string>.Pederson
It came up for me with protocol buffer definitions that used a Java keyword. Code generation is really useful, but it's harder to make it work in a language-agnostic way if target languages forbid you to be agnostic about them.Witcher
G
31

No, there is no way. That's why they're labeled "reserved".

Gershom answered 8/1, 2009 at 11:49 Comment(3)
Adding a " _ " in front of a reserved keyword like "_new" is the closest thing you'll get.Hutch
@Hutch _ is not allowed everywhere in vrabiel names, for example not in lambda parametersCobalt
@Cobalt You are wrong.Autohypnosis
D
13

Most often this issue comes up for "class", in this case it is customary to write "clazz".

Dirigible answered 8/1, 2009 at 11:54 Comment(2)
Is there a best practices alternatives list for all keywords?Nephology
In Python PEP8 recommend to use single_trailing_underscore_ to avoid name clashes with keywords.Dirigible
B
8

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.

Bosco answered 14/1, 2009 at 20:18 Comment(5)
Down voted because these kinds of tricks can lead to bugs and behavior that is not easily understood. Why not name it 'n3w' or anything else as it is intended to change the behavior.Antidote
@CodeMonkeyKing, unfortunately not everyone and not in every scenario follows best naming conventions and it is entirely possible that someone might come across a piece of code that included an identifier looking exactly as a reserved word and, perplexingly, compiled without errors. This answer would come to the rescue then. Besides it is answering the actual question being asked. "Whether anyone should be doing it is a totally different matter."Bosco
If I parse the OP's question exactly the answer you suggest only appears to the human eye to be a keyword and is not a "tricky way to use a Java reserved word". I would say from experience that these are the most difficult bugs to find. The real answer to this question is that reserved keywords are in fact reserved.Antidote
I feel like this answer deserves a "Don't try this at home (or in the workplace)" label.Sue
@ChrisKerekes Neh... just expect people to understand why this is a terribly bad thing to do.Kingbolt
P
7

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
Proselytism answered 8/1, 2009 at 11:56 Comment(0)
D
4

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!

Demobilize answered 8/1, 2009 at 11:59 Comment(0)
P
4

In Scala you can use backticks. For example: myVarialbe.`class`

Palestine answered 12/9, 2012 at 17:21 Comment(0)
B
3

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.

Bufflehead answered 9/1, 2009 at 0:3 Comment(1)
This is similar to @identifier in C#, although it doesn't end in the same result (in C# the '@' does not become part of the identifier)Peart
T
3

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;
}
Tocantins answered 25/11, 2016 at 13:18 Comment(1)
Glad to be of help @jake gaston It's workaround i needed at one Project which already had defined variables which couldn't be changed.Tocantins
B
2

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?";
  }
}
Boehmenism answered 8/1, 2009 at 11:49 Comment(1)
Technically - you never fool the compiler as the above example is completely legal Java.Antidote
L
2

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.

Logarithm answered 8/1, 2009 at 16:37 Comment(0)
H
2

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.

Harebrained answered 8/11, 2009 at 21:2 Comment(0)
K
1

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.

Kissie answered 26/11, 2018 at 15:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.