การตรวจสอบ Identifier (ตัวระบุชื่อ) ที่ถูกต้องใน Java
หมายเหตุ: โค้ดต้นฉบับตรวจสอบ "Valid Identifier" (ชื่อตัวแปร/คลาส/เมธอดที่ถูกต้อง) ไม่ใช่ "Keyword" (คีย์เวิร์ดสงวนไว้ เช่น if, class, public) เนื่องจากคีย์เวิร์ด ไม่สามารถใช้เป็น Identifier ได้
กฎ Identifier ใน Java
- ขึ้นต้นด้วย: ตัวอักษร (A-Z, a-z), Underscore (_), Dollar sign ($)
- ตัวถัดไป: ตัวอักษร, ตัวเลข (0-9), _, $
- Case-sensitive
- ห้ามเป็น Keyword/Reserved word (
class,int,forฯลฯ) - ไม่จำกัดความยาว
ตัวอย่างโค้ดตรวจสอบ Identifier (ปรับปรุงจากต้นฉบับ)
import java.util.*;
public class IdentifierValidator {
// ตรวจสอบ Identifier ที่ถูกต้อง (รวม $ และ Unicode letters)
public static boolean isValidIdentifier(String str) {
if (str == null || str.isEmpty()) {
return false;
}
// ตรวจสอบ Keywords
if (isKeyword(str)) {
return false;
}
// ตัวอักษรแรก: ต้องเป็น Letter, _, หรือ $
char first = str.charAt(0);
if (!Character.isJavaIdentifierStart(first)) {
return false;
}
// ตัวต่อไป: ต้องเป็น Letter, Digit, _, หรือ $
for (int i = 1; i < str.length(); i++) {
if (!Character.isJavaIdentifierPart(str.charAt(i))) {
return false;
}
}
return true;
}
// รายการ Keywords ใน Java (รวม Reserved words)
private static final Set KEYWORDS = Set.of(
"abstract", "assert", "boolean", "break", "byte", "case", "catch", "char",
"class", "const", "continue", "default", "do", "double", "else", "enum",
"extends", "final", "finally", "float", "for", "goto", "if", "implements",
"import", "instanceof", "int", "interface", "long", "native", "new",
"package", "private", "protected", "public", "return", "short", "static",
"strictfp", "super", "switch", "synchronized", "this", "throw", "throws",
"transient", "try", "void", "volatile", "while",
// Reserved literals
"true", "false", "null",
// Contextual keywords (Java 9+)
"exports", "module", "open", "opens", "provides", "requires", "to", "transitive", "uses", "with",
// Preview/Preview features
"record", "sealed", "non-sealed", "permits", "yield"
);
private static boolean isKeyword(String str) {
return KEYWORDS.contains(str);
}
public static void main(String[] args) {
String[] testCases = {
"validName", "_private", "$dollar", "name123", "HelloWorld",
"123invalid", "has-space", "has@symbol", "class", "int", "null", "true"
};
for (String test : testCases) {
System.out.printf("%-15s : %s%n", test, isValidIdentifier(test) ? "✅ Valid" : "❌ Invalid");
}
}
}
ผลลัพธ์
validName : ✅ Valid
_private : ✅ Valid
$dollar : ✅ Valid
name123 : ✅ Valid
HelloWorld : ✅ Valid
123invalid : ❌ Invalid (ขึ้นต้นตัวเลข)
has-space : ❌ Invalid (มีช่องว่าง)
has@symbol : ❌ Invalid (@ ไม่ได้รับอนุญาต)
class : ❌ Invalid (Keyword)
int : ❌ Invalid (Keyword)
null : ❌ Invalid (Reserved literal)
true : ❌ Invalid (Reserved literal)
วิธีตรวจสอบ Keyword โดยเฉพาะ
public static boolean isJavaKeyword(String str) {
return KEYWORDS.contains(str);
}
// ใช้ Character class (Java 12+) - ตรวจสอบ Identifier ได้ แต่ไม่เช็ค Keyword
Character.isJavaIdentifierStart('가'); // true (Unicode letter)
Character.isJavaIdentifierPart('1'); // true
การใช้ Regex (Alternative)
// Regex สำหรับ Identifier (ASCII only)
private static final Pattern IDENTIFIER_PATTERN = Pattern.compile("^[a-zA-Z_$][a-zA-Z0-9_$]*$");
public static boolean isValidIdentifierRegex(String str) {
return str != null && IDENTIFIER_PATTERN.matcher(str).matches() && !isKeyword(str);
}
สรุป
- ใช้
Character.isJavaIdentifierStart/Partสำหรับรองรับ Unicode เต็มรูปแบบ - ต้องเช็ค Keywords แยกต่างหาก (Character class ไม่เช็ค)
- Keyword ไม่ใช่ Identifier ที่ถูกต้อง
- Regex แบบ ASCII เร็วกว่า แต่ไม่รองรับ Unicode