Any risk using a single dollar sign `$` as a java class name?
Asked Answered
T

5

16

Originally I was using the underscore _ as a class name. The new Java8 compiler complains that it "might not be supported after Java SE 8". I changed that to $, and there is no warning any more. However I remember that $ is used by Java to indicate an inner/embedded class in the byte code. I am wondering if there is any risk to use a dollar sign $ as a class name

Some background to this question. What I want to do is to overcome the fact that Java doesn't support pure function, and the _ or $ is to put an namespace to encapsulate some very generic concept (classes/static methods). and neither do I have a good name for this, nor do I want the lib user type too many things to reference that namespace. Here is the code showing what I am doing under the way: https://github.com/greenlaw110/java-tool/blob/master/src/main/java/org/osgl/_.java

Taratarabar answered 22/10, 2013 at 22:34 Comment(9)
It is generally a bad idea to use strange names for classes, methods and variables. In Java less than other languages (C/C++), but still it's not a great idea, I think. The name of a class should briefly describe its purpose.Vermiculite
Anyway, I think it's ok, if you know what you're doing. The dollar has no special meaning. It is used to generate unambiguous names for nested classes. Since no two classes can exist in the same package with the same name, using the containing class name as a prefix guarantees that there are no overlaps between classes nested inside different first-level classes.Vermiculite
@Pshemo, seriously I think I should expose more context to avoid comments like the one you posted. The thing I want to do is to overcome the fact that Java doesn't support pure function, and the _ or $ is to put an namespace to encapsulate some very generic concept (classes/static methods). and neither do I have a good name for this, nor do I want the lib user type too many things to reference that namespace. Check out github.com/greenlaw110/java-tool/blob/master/src/main/java/org/…Taratarabar
@green I see your point, but I'm still against it. If every library developer did this, the names would conflict, and users of multiple libraries would be forced to type the fully qualified class name to avoid ambiguities. I'd prefer a concise, but meaningful name.Vermiculite
@green: if you're concerned with JDK 8, why even bother, after JDK8 comes around with better support for functions and the like?Promiscuous
@GiulioFranco, any good name you recommend for my case?Taratarabar
@green any name that makes sense. The name of your library might be a good idea, or <NameOfYourLibrary>Helpers/Facade. Btw if the library user doesn't want to type the class name before static methods, (s)he can use a static import your.library.LibraryHelpers.* docs.oracle.com/javase/1.5.0/docs/guide/language/…Vermiculite
Underscore might not be supported? Smells like type classes are coming...Hysteria
I looked everywhere and Selenide is the only lib I could find using this pattern. I wish there was some info on using this pattern somewhere because I think it is nifty.Alexandretta
D
25

It is bad style, and potentially risky to use $ in any identifier in Java. The reason it is risky is that the $ character is reserved for the use of the Java toolchain and third-party language tools.

  • It is used by Java compilers in "internal" class names for inner and nested classes.
  • It is used by Java compilers in the names of synthetic attributes.
  • It could be used by third-party code generators (e.g. annotation processors) for various purposes.
  • It could be used by other languages that target the JVM platform, and that might need to co-exist with your code.

You probably won't have technical issues with a plain $ classname at the moment (at least with respect to the standard Java toolchain). But there's always the possibility that this will change in the future:

  • They have (effectively) reserved the right to change this1.
  • There is a precedent for doing this in the _ example.

If you really, really need a one-character classname, it would be better to play it safe and use F or Z or something else that isn't reserved.

But to be honest, I think you'd be better off trying to implement (or just use) a real functional language than trying to shoe-horn a functional programming "system" into Java. Or maybe, just switch to Java 8 ahead of its official release. 'Cos I for one would refuse to read / maintain a Java codebase that looked like jquery.


I don't mean to create a functional lib for Java, just want to create a lib to maintain some common utilities I used. Again, I am a advocate of minimalism and feel suck with things like apache commons. The functional stuff is added to help me easier to manipulate collection(s).

If it is your code, you can do what you like. Make your own decisions. Act on your opinions. Be a "risk taker" ... :-). (Our advice on $, etcetera ... is moot.)

But if you are writing this code for a client or employer, or with the intention of creating a (viable) open source product, then you need to take account of other people's opinion. For example, your coworkers will have a stake in this, given that they may end up maintaining your code.


1 - JLS §3.8 states "The $ character should be used only in mechanically generated source code". That is saying "use it at your peril". The assumption is that folks who build their own source code generators can change them if the standard toolchain uses a bare $ ... but it is harder to change lots of hand written code, and that would be an impediment to upgrading.

Dixil answered 23/10, 2013 at 7:58 Comment(6)
Seriously I don't like $ sign also, that's why I choose _, which gives me a feeling of "default"; Side words: originally I don't mean to create a functional lib for Java, just want to create a lib to maintain some common utilities I used. Again, I am a advocate of minimalism and feel suck with things like apache commons. The functional stuff is added to help me easier to manipulate collection(s).Taratarabar
Why did java allow this when it would cause these ambiguities? How will someone be able to discern if the $ sign means inner class or it is part of the className. eg: Test$String.class. Is this an inner class?Tonl
OK. So your comment is addressed and can be cleaned up.Dixil
@Tonl - "Why did java allow this when it would cause these ambiguities?" - Presumably because they thought it may be necessary. The best advice is to avoid using $ in your source code unless you really, really need to use it. (For example, if you need to explicitly load an inner class in reflective code.)Dixil
@StephenC Well my problems have been solved. It turns out Java class files have enough info to know if dollar sign represents inner class or part of declaration name. So I am guessing java reflect api should work fine with $ sign in names. Just a hunch.Tonl
@GelinLuo while Apache Commons are not ideal in every case they are mostly quite a convenience now and minimalistic when used together with static imports.Tilda
C
3

Huh, you're right, using a $ in a classname works. Eclipse complains that it is against convention, but, if you are sure, you can do it.

The problem (conventionally) with using a $ is that the $ is used in the class hierarchy to indicate nested classes.... for example, the file A.java containing:

class A {
   class SubA {
   }
}

would get compiled to two files:

  1. A.class
  2. A$SubA.class

Which is why, even though $ works, it is ill advised because parsing the jars may be more difficult... and you run the risk of colliding two classes and causing other issues

EDIT, I have just done a test with the following two Java files (in the default package)

public class A {
    private static final class SubA {
        public String toString() {
            return "I am initializing Nested SUBA";
        }
    }

    private static final SubA sub = new SubA();
    public A() {
        System.out.println("What is " + sub.toString());
    }
}



public class A$SubA {
    @Override
    public String toString() {
        return "I am A$SubA";
    }
}


public class MyMain {
    public static void main(String[] args) {
        System.out.println(new A());
        System.out.println(new A$SubA());
    }
}

And the code will not compile.....

Two problems, type A$SubA is already defined, and can't reference a nested class A$SubA by it's binary name.

Cenac answered 22/10, 2013 at 22:41 Comment(4)
This is not my case. As I said what I intend to do is using a single $ as the class name.Taratarabar
This won't be an issue in the depicted case (there is only one class which is named "$")Vermiculite
@Cenac This is off the topic. The library is an endeavour to create something new but might seems weird to the guys who are used to those thirtyCharsLongVariableOrMethodNames in traditional JEE world. The version one is already put into company project usage and some of my other OS project like (github.com/greenlaw110/java-storage). It's not a bad experience honestly. Anyway I think it's a matter of taste and if you do think there are big problems, please create an issue in github and I will follow up thereTaratarabar
I don't see how this answer helps - but nice experiment with expecting results though.Yumuk
S
2

Yes, to be pedantic about answering your question there is a risk. As some other folks have mentioned, it violates java naming conventions. So the risk is that with future versions of the JDK this may cause problems. But beyond that, and some issues if you try to use nested classes you should be fine.

Stable answered 22/10, 2013 at 22:53 Comment(0)
H
2

I think you're trying to avoid ugly names like Util.andThen. Consider using static imports. That lets you import all the methods in the header import static org.ogsl.Util.*, so then you can simply use you andThen without any prefix at all.

Humidistat answered 12/6, 2015 at 4:3 Comment(2)
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes.Coatee
@HarshalPatil: This does appear to include the essentials here: use static imports like example, more docs here.Lindgren
A
0

The Selenide project does it. Just look at the top of this documentation: https://selenide.org/documentation.html

Maybe it is a more acceptable thing to do only in test code.

API ref: https://selenide.org/javadoc/current/com/codeborne/selenide/Selenide.html

Alexandretta answered 17/3, 2020 at 20:17 Comment(1)
Selenide does it with methods. It is a completely different story to using $ in a class name. There are no potential collisions with nested classes and there are no problems with such method names in Eclipse.Tilda

© 2022 - 2024 — McMap. All rights reserved.