Reputation: 703
Is there a method in Java to check if a string can be used as a class name?
Upvotes: 14
Views: 16481
Reputation: 82461
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);
}
Upvotes: 29
Reputation: 2814
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;
}
Upvotes: 5
Reputation: 3780
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()
Upvotes: 6
Reputation: 41220
yap -
Class.forName(String className);
It returns the Class object associated with the class or interface with the given string name.
And throws Exceptions
LinkageError - if the linkage fails
ExceptionInInitializerError - if the initialization provoked by this method fails
ClassNotFoundException - if the class cannot be located
Upvotes: 0