一、核心对比速览

方法 功能 返回 true 的典型字符 用途
Character.isISOControl(ch) 是否为 ISO 控制字符 \n, \t, \r, \b, \u007F 过滤不可见控制符
Character.isDefined(ch) 是否在 Unicode 中定义 'A', '中', 🙂, \n, ' ' 验证字符合法性

🔑 一句话总结

  • isISOControl:判断是不是“看不见的控制指令”
  • isDefined:判断是不是“Unicode 认可的合法字符”

二、Character.isISOControl() 详解

2.1 定义

public static boolean isISOControl(char ch)
public static boolean isISOControl(int codePoint)
  • 判断字符是否属于 ISO/IEC 6429 标准定义的控制字符。
  • 包括:
    • C0 控制字符\u0000\u001F(如 \n=U+000A, \t=U+0009
    • DEL\u007F
    • C1 控制字符\u0080\u009F(扩展控制字符)

✅ 常见控制字符:换行符 \n、制表符 \t、回车 \r、退格 \b

2.2 示例代码

System.out.println(Character.isISOControl('\n'));     // true
System.out.println(Character.isISOControl('\t'));     // true
System.out.println(Character.isISOControl('\r'));     // 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: Next Line)

2.3 使用场景

  • 清理日志或文本中的不可见控制字符
  • 验证用户输入是否包含非法控制符
  • 数据序列化前过滤控制字符

三、Character.isDefined() 详解

3.1 定义

public static boolean isDefined(char ch)
public static boolean isDefined(int codePoint)
  • 判断字符是否在 Unicode 标准中被正式分配(defined)
  • 返回 true 如果:
    • 是字母、数字、标点、符号、控制字符、emoji 等任何 已分配的码位
  • 返回 false 如果:
    • 未分配码位(如 \uFFFE, \uFFFF
    • 代理对(Surrogates)\uD800-\uDFFF
    • 非字符(Non-characters):如 \uFDD0-\uFDEF, \uFFFE, \uFFFF

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(私用区,已定义)

3.3 使用场景

  • 验证字符串是否包含非法 Unicode 码点
  • 国际化文本处理中的字符校验
  • 防止恶意输入使用未定义码位

四、关键区别与常见误区

✅ 正确认识:isISOControl() vs isDefined()

字符 isISOControl() isDefined() 说明
'A' false true 普通字符
' '(空格) false true 空格不是控制字符
\t(制表符) true true 控制字符也是定义字符
\n(换行) true true 同上
\u007F(DEL) true true 删除符
\uFFFE false false 非字符,未定义
\uD800 true(部分) false 代理对,未定义

🔁 重要关系
所有 isISOControl(ch)true 的字符,isDefined(ch) 也一定是 true
但反过来不成立。


❌ 常见误区

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

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

✅ 正确做法:使用 !Character.isISOControl(ch) && Character.isDefined(ch) 判断“合法可见字符”


误区 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() 更广。


五、最佳实践

✅ 实践 1:清理控制字符

public static String cleanControlChars(String str) {
    if (str == null) return null;
    return str.codePoints()
              .filter(cp -> !Character.isISOControl(cp))
              .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
              .toString();
}

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

public static boolean isValidText(String str) {
    return str.codePoints().allMatch(Character::isDefined);
}

✅ 实践 3:安全处理用户输入

if (Character.isDefined(ch) && !Character.isISOControl(ch)) {
    // 是合法 Unicode 字符,且不是控制字符 → 安全使用
    buffer.append(ch);
}

六、总结:使用口诀

🔑 “isISOControl 查控制,isDefined 看定义,控制都 defined,defined 不都控”

✅ 核心要点回顾:

方法 用途 推荐场景
isISOControl() 过滤 \n, \t 等控制符 日志清洗、安全过滤
isDefined() 验证字符是否合法 输入校验、国际化处理