16

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

这个问题的一些背景。我要做的是克服Java不支持纯函数的事实,而_或$是放置一个命名空间来封装一些非常通用的概念(类/静态方法)。而且我也没有一个好名字,我也不希望 lib 用户键入太多东西来引用该命名空间。这是显示我正在做的事情的代码:https ://github.com/greenlaw110/java-tool/blob/master/src/main/java/org/osgl/_.java

4

5 回答 5

24

这是一种不好的风格,并且$在 Java 中的任何标识符中使用都有潜在的风险。有风险的原因是该$字符是为 Java 工具链和第三方语言工具的使用而保留的。

  • Java 编译器在内部和嵌套类的“内部”类名中使用它。
  • Java 编译器在合成属性的名称中使用它。
  • 它可以被第三方代码生成器(例如注释处理器)用于各种目的。
  • 它可以被针对 JVM 平台的其他语言使用,并且可能需要与您的代码共存。

目前,您可能不会遇到纯$类名的技术问题(至少就标准 Java 工具链而言)。但总有可能在未来发生变化:

  • 他们(有效地)保留了更改此1的权利。
  • 示例中有这样做的先例_

如果您真的,真的需要一个单字符的类名,最好安全地使用它并使用FZ其他没有保留的东西。

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


我并不是要为 Java 创建一个函数库,只是想创建一个库来维护我使用的一些常用实用程序。再说一次,我是极简主义的倡导者,我觉得像 apache commons 这样的东西很糟糕。添加了功能性内容以帮助我更轻松地操作集合。

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

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


1 - JLS §3.8规定“该$字符只能用于机械生成的源代码”。这就是说“使用它,后果自负”。假设是,如果标准工具链使用裸代码,则构建自己的源代码生成器的人可以更改$它们……但是更改大量手写代码会更加困难,这将成为升级的障碍。

于 2013-10-23T07:58:31.720 回答
3

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

使用 a 的问题(通常)$$在类层次结构中用于指示嵌套类....例如,文件 A.java 包含:

class A {
   class SubA {
   }
}

会被编译成两个文件:

  1. 一类
  2. A$SubA.class

这就是为什么即使$有效,也不建议这样做,因为解析罐子可能会更困难......而且你冒着碰撞两个类并导致其他问题的风险

编辑,我刚刚对以下两个 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());
    }
}

而且代码不会编译.....

两个问题,类型 A$SubA 已经定义,并且不能通过它的二进制名称引用嵌套类 A$SubA。

于 2013-10-22T22:41:33.920 回答
2

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

于 2013-10-22T22:53:44.023 回答
2

我认为您正在尝试避免使用丑陋的名称,例如Util.andThen. 考虑使用静态导入。这使您可以导入 header 中的所有方法import static org.ogsl.Util.*,因此您可以简单地使用您,andThen而无需任何前缀。

于 2015-06-12T04:03:43.820 回答
0

Selenide 项目做到了。只需查看此文档的顶部: https ://selenide.org/documentation.html

也许只在测试代码中做更容易接受的事情。

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

于 2020-03-17T20:17:22.223 回答