Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check if the class name is valid?

Is there a method in Java to check if a string can be used as a class name?

like image 950
Maxii Avatar asked Dec 20 '12 19:12

Maxii


3 Answers

SourceVersion.isName can be used to check fully qualified names.

If no .s should be allowed, the check can be done this way:

boolean isValidName (String className) {
    return SourceVersion.isIdentifier(className) && !SourceVersion.isKeyword(className);
}
like image 91
fabian Avatar answered Nov 20 '22 07:11

fabian


Quite simply, with the Class.forName(String name) method, which can be used to test this as follows:

public static boolean classExists(String className)
{
    try
    {
        Class.forName(className);
        return true;
    }
    catch(ClassNotFoundException ex)
    {
        return false;
    }
}

Edit: If, as dashrb said, you're asking for a way to determine if a String can be used as a class name (rather than if there already is a class by that name), then what you need is a combination of the method I posted above (with the booleans flipped, as you can't reuse class names), and in combination with a check to see if the String is a Java-reserved keyword. I had a similar problem recently and made a utility class for it which you can find here. I won't write it for you, but you basically just need to add in a check for !JavaKeywords.isKeyword(className).

Edit 2: And of course, if you want to also enforce generally accepted coding standards, you could just make sure that the class name starts with a capital letter with:

return Character.isUpperCase(className.charAt(0));

Edit 3: As Ted Hopp points out, even containing a java keyword invalidates a class name, and as JavaKeywords is used in one of my production applications, I have made an updated version which includes the method containsKeyword(String toCheck) which will also check for this eventuality. The method is as follows (please note you need the list of keywords in the class too):

public static boolean containsKeyword(String toCheck)
{
    toCheck = toCheck.toLowerCase();
    for(String keyword : keywords)
    {
        if(toCheck.equals(keyword) || toCheck.endsWith("." + keyword) ||
           toCheck.startsWith(keyword + ".") || toCheck.contains("." + keyword + "."))
        {
            return true;
        }//End if
    }//End for
    return false;
}//End containsKeyword()
like image 38
MrLore Avatar answered Nov 20 '22 07:11

MrLore


I used the list of java keywords kindly offered by MrLore.

private static final Set<String> javaKeywords = new HashSet<String>(Arrays.asList(
    "abstract",     "assert",        "boolean",      "break",           "byte",
    "case",         "catch",         "char",         "class",           "const",
    "continue",     "default",       "do",           "double",          "else",
    "enum",         "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"
));

private static final Pattern JAVA_CLASS_NAME_PART_PATTERN =
    Pattern.compile("[A-Za-z_$]+[a-zA-Z0-9_$]*");

public static boolean isJavaClassName(String text) {
    for (String part : text.split("\\.")) {
        if (javaKeywords.contains(part) ||
                !JAVA_CLASS_NAME_PART_PATTERN.matcher(part).matches()) {
            return false;
        }           
    }
    return text.length() > 0;
}
like image 5
tcb Avatar answered Nov 20 '22 06:11

tcb