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

CerebralFart
  • 3,336
  • 5
  • 26
  • 29
Gelin Luo
  • 14,035
  • 27
  • 86
  • 139
  • 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. – Giulio Franco Oct 22 '13 at 22:38
  • 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. – Giulio Franco Oct 22 '13 at 22:41
  • @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 https://github.com/greenlaw110/java-tool/blob/master/src/main/java/org/osgl/_.java – Gelin Luo Oct 22 '13 at 22:47
  • @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. – Giulio Franco Oct 22 '13 at 22:56
  • @green: if you're concerned with JDK 8, why even bother, after JDK8 comes around with better support for functions and the like? – Louis Wasserman Oct 22 '13 at 22:56
  • @GiulioFranco, any good name you recommend for my case? – Gelin Luo Oct 22 '13 at 23:00
  • 2
    @green any name that makes sense. The name of your library might be a good idea, or 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.*` http://docs.oracle.com/javase/1.5.0/docs/guide/language/static-import.html – Giulio Franco Oct 22 '13 at 23:03
  • Underscore might not be supported? Smells like type classes are coming... – Alex Pakka Oct 30 '13 at 03:07
  • 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. – djangofan Mar 17 '20 at 20:24

5 Answers5

24

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 boss needs to have an informed opinion on how maintainable your code will be if you find a better paying job somewhere else. In general, will the next guy be able to figure it out, keep your code, fresh, etc ... or will it be consigned to the dustbin?


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.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • 1
    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). – Gelin Luo Oct 23 '13 at 10:33
  • 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? – user13947194 Jul 07 '23 at 17:07
  • OK. So your comment is addressed and can be cleaned up. – Stephen C Jul 10 '23 at 04:21
  • @user13947194 - *"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.) – Stephen C Jul 10 '23 at 04:29
  • @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. – user13947194 Jul 11 '23 at 02:27
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.

rolfl
  • 17,539
  • 7
  • 42
  • 76
  • 1
    This is not my case. As I said what I intend to do is using a single `$` as the class name. – Gelin Luo Oct 22 '13 at 22:58
  • 2
    This won't be an issue in the depicted case (there is only one class which is named "$") – Giulio Franco Oct 22 '13 at 22:59
  • @rolfl 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 (https://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 there – Gelin Luo Oct 22 '13 at 23:22
  • I don't see how this answer helps - but nice experiment with expecting results though. – Stefan Jun 11 '15 at 11:37
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.

Akshay Rangnekar
  • 272
  • 2
  • 11
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.

Nathan Tuggy
  • 2,237
  • 27
  • 30
  • 38
  • 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. – Harshal Patil Jun 12 '15 at 04:33
  • @HarshalPatil: This *does* appear to include the essentials here: use static imports like `example`, more docs here. – Nathan Tuggy Jun 12 '15 at 05:20
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

djangofan
  • 28,471
  • 61
  • 196
  • 289