Java类文件可以使用保留关键字作为名称吗? - java

我知道Java可编译程序设计语言不是一种与JVM执行Java字节码格式相同的语言。有些示例在.class格式中有效,但在.java源代码中无效,例如无构造函数的类和合成方法。

  • 如果我们使用保留的Java语言关键字(例如intwhile)作为类,方法或字段名称来手工制作.class文件,那么Java虚拟机会接受该文件进行加载吗?
  • 如果已加载该类,是否表示访问该类或成员的唯一方法是通过Java反射,因为该名称在Java编程语言中在语法上是非法的?
  • 参考方案

    在字节码级别上对类名称的唯一限制是它们不能包含字符[.;,并且它们的最大长度为65535个字节。除其他外,这意味着您可以自由使用保留字,空格,特殊字符,Unicode甚至是换行符之类的怪异东西。

    从理论上讲,您甚至可以在类名中使用空字符,但是由于文件名中不可能包含空字符,因此您不能在jar中包含这样的类文件。您也许可以动态创建和加载一个。

    这是您可以做的一些事情的示例(用Krakatau程序集编写):

    ; Entry point for the jar
    .class Main
    .super java/lang/Object
    
    .method public static main : ([Ljava/lang/String;)V
        .limit stack 10
        .limit locals 10
        invokestatic int                                hello ()V
        invokestatic "-42"                              hello ()V
        invokestatic ""                                 hello ()V
        invokestatic "  some  whitespace and \t tabs"   hello ()V
        invokestatic "new\nline"                        hello ()V
        invokestatic 'name with "Quotes" in it'         hello ()V
        return
    .end method
    .end class
    
    
    .class int
    .super java/lang/Object
    .method public static hello : ()V
        .limit stack 2
        .limit locals 0
        getstatic java/lang/System out Ljava/io/PrintStream;
        ldc "Hello from int"
        invokevirtual java/io/PrintStream println (Ljava/lang/Object;)V
        return
    .end method
    .end class
    
    .class "-42"
    .super java/lang/Object
    .method public static hello : ()V
        .limit stack 2
        .limit locals 0
        getstatic java/lang/System out Ljava/io/PrintStream;
        ldc "Hello from -42"
        invokevirtual java/io/PrintStream println (Ljava/lang/Object;)V
        return
    .end method
    .end class
    
    ; Even the empty string can be a class name!
    .class ""
    .super java/lang/Object
    .method public static hello : ()V
        .limit stack 2
        .limit locals 0
        getstatic java/lang/System out Ljava/io/PrintStream;
        ldc "Hello from "
        invokevirtual java/io/PrintStream println (Ljava/lang/Object;)V
        return
    .end method
    .end class
    
    .class "  some  whitespace and \t tabs"
    .super java/lang/Object
    .method public static hello : ()V
        .limit stack 2
        .limit locals 0
        getstatic java/lang/System out Ljava/io/PrintStream;
        ldc "Hello from   some  whitespace and \t tabs"
        invokevirtual java/io/PrintStream println (Ljava/lang/Object;)V
        return
    .end method
    .end class
    
    .class "new\nline"
    .super java/lang/Object
    .method public static hello : ()V
        .limit stack 2
        .limit locals 0
        getstatic java/lang/System out Ljava/io/PrintStream;
        ldc "Hello from new\nline"
        invokevirtual java/io/PrintStream println (Ljava/lang/Object;)V
        return
    .end method
    .end class
    
    .class 'name with "Quotes" in it'
    .super java/lang/Object
    .method public static hello : ()V
        .limit stack 2
        .limit locals 0
        getstatic java/lang/System out Ljava/io/PrintStream;
        ldc "Hello from name with \"Quotes\" in it"
        invokevirtual java/io/PrintStream println (Ljava/lang/Object;)V
        return
    .end method
    .end class
    

    执行输出:

    Hello from int
    Hello from -42
    Hello from
    Hello from   some  whitespace and        tabs
    Hello from new
    line
    Hello from name with "Quotes" in it
    

    有关JVM规范中规则的确切引用,请参见Holger's answer。

    Java-搜索字符串数组中的字符串 - java

    在Java中,我们是否有任何方法可以发现特定字符串是字符串数组的一部分。我可以避免出现一个循环。例如String [] array = {"AA","BB","CC" }; string x = "BB" 我想要一个if (some condition to tell wheth…

    Java-非泛型类扩展了泛型类 - java

    我想知道如何(如果可能)创建一个类,它是泛型类的特定类型。具体来说,我有一个实现所有必需方法的abstract class Stack<Type>,我想有一个class StackInteger,而StackInteger的实例也是Stack<Integer>的实例。我看到我可以做这样的事情:class StackInteger { …

    Java Globbing模式以匹配目录和文件 - java

    我正在使用递归函数遍历根目录下的文件。我只想提取*.txt文件,但不想排除目录。现在,我的代码如下所示:val stream = Files.newDirectoryStream(head, "*.txt") 但是这样做将不会匹配任何目录,并且返回的iterator()是False。我使用的是Mac,所以我不想包含的噪音文件是.DS_ST…

    Java RegEx中的单词边界\ b - java

    我在使用\b作为Java Regex中的单词定界符时遇到困难。对于text = "/* sql statement */ INSERT INTO someTable"; Pattern.compile("(?i)\binsert\b");找不到匹配项Pattern insPtrn = Pattern.compile(&…

    Java Double与BigDecimal - java

    我正在查看一些使用双精度变量来存储(360-359.9998779296875)结果为0.0001220703125的代码。 double变量将其存储为-1.220703125E-4。当我使用BigDecimal时,其存储为0.0001220703125。为什么将它双重存储为-1.220703125E-4? 参考方案 我不会在这里提及精度问题,而只会提及数字…