一、方法概览

方法 功能 返回类型
Character.isISOControl(int codePoint)
Character.isISOControl(char ch)
判断字符是否为 ISO 6429 控制字符 boolean
Character.isDefined(int codePoint)
Character.isDefined(char ch)
判断字符是否在 Unicode 标准中定义 boolean

⚠️ 两者都用于字符分类判断,但语义和用途完全不同。


二、Character.isISOControl() 详解

2.1 方法定义

public static boolean isISOControl(char ch)
public static boolean isISOControl(int codePoint)
  • 功能:判断指定字符是否为 ISO/IEC 6429(也称 ANSI 控制字符)定义的控制字符。
  • 控制字符范围
    • \u0000\u001FC0 控制字符(如 \n, \t, \r, \b
    • \u007FDEL(删除)
    • \u0080\u009FC1 控制字符(扩展控制字符)

✅ 常见 ISO 控制字符:\t (Tab), \n (换行), \r (回车), \b (退格), \f (换页)

2.2 示例代码

System.out.println(Character.isISOControl('\n'));     // true
System.out.println(Character.isISOControl('\t'));     // true
System.out.println(Character.isISOControl(' '));      // false(空格不是控制字符)
System.out.println(Character.isISOControl('\u007F')); // true(DEL)
System.out.println(Character.isISOControl('A'));      // false
System.out.println(Character.isISOControl('\u0085')); // true(C1 控制字符:NEL)

2.3 使用场景

  • 过滤不可见控制字符(如日志清洗)
  • 验证用户输入是否包含非法控制符
  • 文本序列化/传输前清理控制字符

2.4 注意事项

  • 空格 ' ' 不是控制字符,返回 false
  • 制表符 \t 是控制字符,返回 true
  • C1 控制字符(U+0080 到 U+009F)也包含在内

三、Character.isDefined() 详解

3.1 方法定义

public static boolean isDefined(char ch)
public static boolean isDefined(int codePoint)
  • 功能:判断字符是否在 Unicode 标准中被定义为一个字符
  • 返回 true 的情况
    • 字符是字母、数字、标点、符号、控制字符等任何 已分配的 Unicode 码位
  • 返回 false 的情况
    • 未分配的码位(Private Use, Surrogates, Non-Characters)

3.2 示例代码

System.out.println(Character.isDefined('A'));           // true
System.out.println(Character.isDefined('中'));          // true
System.out.println(Character.isDefined('🙂'));          // true(emoji)
System.out.println(Character.isDefined('\n'));          // true(控制字符也是定义的)
System.out.println(Character.isDefined('\u0000'));      // true(NUL 是定义的)
System.out.println(Character.isDefined('\uFFFE'));      // false(非字符)
System.out.println(Character.isDefined('\uFFFF'));      // false(非字符)
System.out.println(Character.isDefined('\uE000'));      // true(虽然在私用区,但已定义)

🔍 Unicode 非字符(Non-characters):如 \uFFFE, \uFFFF, \u1FFFE 等,保留不用,isDefined() 返回 false

3.3 使用场景

  • 验证 Unicode 字符有效性
  • 处理用户输入时过滤非法码点
  • 国际化文本处理中的字符校验

四、对比总结:isISOControl() vs isDefined()

特性 isISOControl() isDefined()
判断内容 是否为 ISO 控制字符 是否为 Unicode 定义字符
范围 \u0000-\u001F, \u007F, \u0080-\u009F 所有已分配的 Unicode 码位
空格 ' ' false true
换行 \n true true
字母 'A' false true
未分配码位 可能 falsetrue(取决于值) false
典型用途 过滤控制字符 验证字符合法性

关键区别

  • isISOControl()“黑名单”:只标记特定控制字符
  • isDefined()“白名单”:标记所有合法 Unicode 字符

五、常见错误与注意事项

❌ 错误 1:认为 isDefined() 可以判断“可见字符”

// 错误理解
if (Character.isDefined(ch)) {
    // 认为 ch 是“可见字符” → ❌ 错误!
    // 实际上 '\n', '\t' 也是 defined
}

✅ 正确做法:使用 Character.isISOControl()Character.isWhitespace() 过滤不可见字符


❌ 错误 2:混淆 isISOControl()isWhitespace()

System.out.println(Character.isWhitespace(' '));   // true
System.out.println(Character.isISOControl(' '));   // false

System.out.println(Character.isWhitespace('\t'));  // true
System.out.println(Character.isISOControl('\t'));  // true

isWhitespace() 包括空格、Tab、换行等“空白”,而 isISOControl() 更广。


❌ 错误 3:对 null 或无效码点调用

char ch = (char) 0xFFFF; // 无效码点
boolean defined = Character.isDefined(ch); // false(正确)
boolean control = Character.isISOControl(ch); // false(在 C1 范围外)

✅ 方法本身安全,但需理解返回值含义。


六、最佳实践

✅ 实践 1:清理文本中的控制字符

public static String removeControlChars(String str) {
    if (str == null) return null;
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < str.length(); ) {
        int codePoint = str.codePointAt(i);
        if (!Character.isISOControl(codePoint)) {
            sb.appendCodePoint(codePoint);
        }
        i += Character.charCount(codePoint);
    }
    return sb.toString();
}

✅ 实践 2:验证输入字符合法性

public static boolean isValidUnicode(String str) {
    for (int i = 0; i < str.length(); ) {
        int codePoint = str.codePointAt(i);
        if (!Character.isDefined(codePoint)) {
            return false;
        }
        i += Character.charCount(codePoint);
    }
    return true;
}

✅ 实践 3:结合使用(过滤未定义 + 控制字符)

if (Character.isDefined(ch) && !Character.isISOControl(ch)) {
    // 是合法 Unicode 字符,且不是控制字符
    process(ch);
}

七、总结:使用口诀

🔑 “isISOControl 查控制,isDefined 看定义,控制不可见,defined 包括它”

✅ 核心要点:

方法 用途 返回 true 的典型值
isISOControl() 判断是否为 控制字符 \n, \t, \r, \u007F
isDefined() 判断是否为 Unicode 定义字符 'A', '中', \n, 🙂

📌 记住

  • 所有 ISO 控制字符都是 isDefined()true
  • isDefined()true 的不一定是控制字符