【问题标题】:Get a list of all Java reserved Keywords获取所有 Java 保留关键字的列表
【发布时间】:2021-09-14 20:09:33
【问题描述】:

我正在寻找一种将Java 中保存的所有关键字检索到某种数据结构中的方法。例如:“for、while、if、else、int、double 等”

我需要对字符串进行名称验证,具体来说,我需要确保它不等于任何 java 关键字。

是否有一种特定的方法可以将所有关键字检索到一个数据结构中?还是我只需要构建一个包含所有这些关键字的正则表达式字符串:“for|while|if|...”并尝试将我的字符串与之匹配?

谢谢

【问题讨论】:

标签: java regex keyword reserved-words


【解决方案1】:

来自axis.apache.org

基本上,Pre-Sort 关键字并将其存储在一个数组中,并在您的关键字上使用 Arrays.binarySearch 以获得 good'ol O(logn) 复杂性

import java.util.Arrays;

    public class MainDemo {
        static final String keywords[] = { "abstract", "assert", "boolean",
                "break", "byte", "case", "catch", "char", "class", "const",
                "continue", "default", "do", "double", "else", "extends", "false",
                "final", "finally", "float", "for", "goto", "if", "implements",
                "import", "instanceof", "int", "interface", "long", "native",
                "new", "null", "package", "private", "protected", "public",
                "return", "short", "static", "strictfp", "super", "switch",
                "synchronized", "this", "throw", "throws", "transient", "true",
                "try", "void", "volatile", "while" };

        public static boolean isJavaKeyword(String keyword) {
            return (Arrays.binarySearch(keywords, keyword) >= 0);
        }

        //Main method
        public static void main(String[] args) {
            System.out.println(isJavaKeyword("void"));

        }

    }

输出:

是的


或者,正如用户 @typeracer、@holger 在 cmets 中建议的那样, 您可以使用SourceVersion.isKeyword("void"),它在内部使用javax.lang.model.SourceVersion 库和Hashset 数据结构,并为您更新列表。

【讨论】:

  • ...并将它们存储在HashSet 中会给您带来O(1) 的复杂性,甚至不需要对它们进行预排序。
  • 好建议,我忘了 Hashset!
  • 我实际上最终实现了您的建议,但我刚刚发现了一个本机 API,它显然自 Java 1.6 以来就存在!见stackoverflow.com/a/54141029/1965404
【解决方案2】:

我很惊讶没有人建议 javax.lang.model.SourceVersion,因为它实际上从 Java 1.6 就已经存在了。

如果您需要检查某个字符串是否为保留关键字,您可以调用:

SourceVersion.isKeyword(str)

如果你真的需要保留关键字的完整列表,你可以从该类的源代码中获取:

private final static Set<String> keywords;
static {
    Set<String> s = new HashSet<String>();
    String [] kws = {
        "abstract", "continue",     "for",          "new",          "switch",
        "assert",   "default",      "if",           "package",      "synchronized",
        "boolean",  "do",           "goto",         "private",      "this",
        "break",    "double",       "implements",   "protected",    "throw",
        "byte",     "else",         "import",       "public",       "throws",
        "case",     "enum",         "instanceof",   "return",       "transient",
        "catch",    "extends",      "int",          "short",        "try",
        "char",     "final",        "interface",    "static",       "void",
        "class",    "finally",      "long",         "strictfp",     "volatile",
        "const",    "float",        "native",       "super",        "while",
        // literals
        "null",     "true",         "false"
    };
    for(String kw : kws)
        s.add(kw);
    keywords = Collections.unmodifiableSet(s);
}

注意:以上源代码来自 Java 1.8,所以如果您是使用不同版本的 Java。事实上,复制它可能根本不是一个好主意——他们将字段设为 private 是有充分理由的——你可能不想让每个新字段都保持最新Java 版本。但是,如果您绝对必须拥有它,请从您自己的 JDK 发行版中的源代码中复制它,请记住,您以后可能必须手动不断更新它。

【讨论】:

    【解决方案3】:

    没有直接的 API 方法。作为替代方案,您可以将它们放在一个数组中并检查输入的关键字是否匹配数组中的关键字。

     public static String[] keys= {  "new",..... } 
    

    然后

     for (int i = 0; i < keys.length; i++) {  
                if (input.equals(keys[i])) {  
                   // TO DO
                }  
            }  
    

    【讨论】:

    • 我可能会使用HashSet 及其contains 方法,但数组也可以解决问题。
    • @Pshemo 同意你的观点 :) 基本思想是在容器中遍历。
    • 其实有一个直接的API方法;见stackoverflow.com/a/54141029/1965404
    【解决方案4】:

    好的,既然没有自动的方法,我将创建一个包含所有关键字的文本文件: List of Java Keywords

    然后在运行时检查文件,将每个关键字插入到数组或数组列表(或正则表达式字符串)中,并在检查名称有效性时检查使用该数据结构。

    谢谢大家

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-03
      相关资源
      最近更新 更多