Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Java

วิธีตรวจสอบว่าสตริงเป็นคีย์เวิร์ด (Keyword) ที่ถูกต้องใน Java

การตรวจสอบ 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