Why does the JVM allow us to name a function starting with a digit in bytecode?

前端 未结 2 1682
情深已故
情深已故 2021-01-14 12:48

Identifiers are well defined by The Java Language Specification, Java SE 7 Edition (§3.8)

An identifier is an unlimited-length sequenc         


        
2条回答
  •  夕颜
    夕颜 (楼主)
    2021-01-14 13:39

    So, is the name of the method actually "99"?

    Real programmers don't use parsers, they use sed:

    javac Test.java
    sed -i 's/\d003f99/\d00299/' Test.class
    java Test
    

    Output:

    99
    100
    

    This works because we know that the method name is stored in the constant pool as plaintext in a Utf8 entry, and JVMS says that Utf8 entries are of form:

    CONSTANT_Utf8_info {
        u1 tag;
        u2 length;
        u1 bytes[length];
    }
    

    so we had something like:

    01 | 00 03 | 'f' '9' '9'
    

    (identifier 3 bytes long) and the sed command replaced 03 | 'f' '9' '9' with 02 | '9' '9' (now 2 bytes long).

    I later checked with javap -v Test.class that sed did what I wanted it to do. Before:

    #18 = Utf8               f99
    

    After:

    #18 = Utf8               99
    

    Having manually edited, run, decompiled and compared the .class to the JVMS, I can only conclude that the method name must be 99 :-)

    So it's just a Java language restriction not present in bytecode.

    Why does Java prevent such names?

    Likely to make the syntax look like C.

    Not starting with digits makes it easier to differentiate identifiers from integer literals for both humans and parsers.

    See also:

    • Why can't variable names start with numbers?
    • https://softwareengineering.stackexchange.com/questions/133381/why-should-identifiers-not-begin-with-a-number

提交回复
热议问题