使用单个美元符号“$”作为java类名有风险吗?

使用单个美元符号“$”作为java类名有风险吗?,java,java-8,javac,Java,Java 8,Javac,最初,我使用下划线\uu作为类名。新的Java8编译器抱怨它“在JavaSE8之后可能不受支持”。我将其更改为$,不再有任何警告。但是我记得Java使用$来表示字节码中的内部/嵌入类。我想知道使用美元符号$作为类名是否有风险 这个问题的一些背景。我想做的是克服Java不支持纯函数这一事实,u或$是放置一个名称空间来封装一些非常通用的概念(类/静态方法)。我对此既没有好名字,也不希望lib用户类型引用太多的名称空间。下面的代码显示了我正在做的事情:嗯,你说得对,在类名中使用$。Eclipse抱怨它

最初,我使用下划线
\uu
作为类名。新的Java8编译器抱怨它“在JavaSE8之后可能不受支持”。我将其更改为
$
,不再有任何警告。但是我记得Java使用
$
来表示字节码中的内部/嵌入类。我想知道使用美元符号
$
作为类名是否有风险


这个问题的一些背景。我想做的是克服Java不支持纯函数这一事实,u或$是放置一个名称空间来封装一些非常通用的概念(类/静态方法)。我对此既没有好名字,也不希望lib用户类型引用太多的名称空间。下面的代码显示了我正在做的事情:

嗯,你说得对,在类名中使用
$
。Eclipse抱怨它违反了惯例,但是,如果您确定,您可以这样做

使用
$
的问题(传统上)是在类层次结构中使用
$
来指示嵌套类。。。。例如,文件A.java包含:

class A {
   class SubA {
   }
}
将被编译为两个文件:

  • A.课堂
  • $SubA.class
  • 这就是为什么,即使
    $
    有效,也不建议这样做,因为解析JAR可能更困难。。。您可能会遇到两个类的冲突,并导致其他问题

    编辑,我刚刚用以下两个Java文件(在默认包中)做了一个测试

    而代码将不会编译…..


    两个问题,类型A$SubA已定义,无法通过其二进制名称引用嵌套类A$SubA。

    是的,在回答您的问题时要学究,存在风险。正如其他人提到的,它违反了java命名约定。因此,风险在于,对于JDK的未来版本,这可能会导致问题。但除此之外,还有一些问题,如果您尝试使用嵌套类,您应该不会有问题

    在Java中的任何标识符中使用
    $
    都是不好的样式,并且可能存在风险。风险在于
    $
    字符是为Java工具链和第三方语言工具保留的

    • Java编译器在内部类和嵌套类的“内部”类名中使用它
    • Java编译器以合成属性的名义使用它
    • 第三方代码生成器(如注释处理器)可将其用于各种用途
    • 它可以被其他针对JVM平台的语言使用,并且可能需要与您的代码共存
    目前,普通的
    $
    类名可能不会有技术问题(至少在标准Java工具链方面)。但这在未来总是有可能改变的:

    • 他们(实际上)保留了改变这一点的权利1
    • 示例中有这样做的先例

    如果您真的需要一个单字符的类名,那么最好谨慎使用
    F
    Z
    或其他非保留的名称

    但老实说,我认为你最好尝试实现(或仅仅使用)一种真正的函数式语言,而不是尝试将函数式编程“系统”移植到Java中。或者,在正式发布之前,只需切换到Java8即可因为我会拒绝读取/维护一个看起来像jquery的Java代码库


    我不是要为Java创建一个函数库,只是想创建一个库来维护我使用的一些常用工具。再一次,我是一个极简主义的倡导者,对ApacheCommons之类的东西感觉很糟糕。添加了功能性内容,以帮助我更容易地操作集合

    如果它是你的代码,你可以做你喜欢的事情。自己做决定。按你的意见行事。做一个“冒险者”…:-)。(我们关于
    $
    ,等等的建议没有实际意义。)

    但是,如果您是为客户或雇主编写此代码,或者是为了创建(可行的)开源产品,那么您需要考虑其他人的意见。例如,如果你在其他地方找到一份薪水更高的工作,你的老板需要对你的代码的可维护性有一个明智的看法。总的来说,下一个家伙能不能弄明白,保持你的代码,保持新鲜,等等。。。还是会被扔进垃圾箱



    1-声明“只能在机械生成的源代码中使用
    $
    字符”。那就是说“使用它会有危险”。假设是,如果标准工具链使用一个简单的
    $
    。。。但是更改大量手写代码比较困难,这将阻碍升级。

    我认为您正在试图避免使用诸如
    Util.和
    之类的丑陋名称。考虑使用。这使您可以导入标题中的所有方法
    import static org.ogsl.Util.*
    ,这样您就可以简单地使用
    ,然后使用
    ,而不使用任何前缀。

    Selenide项目会这样做。只需查看本文档的顶部:

    也许只有在测试代码中才可以接受

    API参考号:

    对于类、方法和变量使用奇怪的名称通常是个坏主意。与其他语言(C/C++)相比,Java语言的使用较少,但我认为这仍然不是一个好主意。一个类的名称应该简单地描述它的用途。无论如何,我认为如果你知道你在做什么,这是可以的。美元没有特殊意义。它用于为嵌套类生成明确的名称。由于同一个包中不能存在具有相同名称的两个类,因此使用包含的类名作为前缀可确保嵌套的类之间不存在重叠
    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());
        }
    }