String.contains() 是判断子串是否存在的直观方法,但需注意:参数不可为 null,区分大小写,空字符串恒返回 true,不支持正则;安全调用须先判空,忽略大小写推荐 regionMatches() 而非 toLowerCase()。

Java 中 String.contains() 是最常用、最直观的子串判断方法,但它有明确的行为边界和常见陷阱,用对了省事,用错了会抛异常或逻辑出错。
contains() 的基本用法和核心规则
它是一个实例方法,调用形式为 str.contains(sub),返回 true 表示连续出现、false 表示未找到。关键点包括:
- 参数类型是
CharSequence(支持String、StringBuilder等),但绝对不能传null,否则立刻抛NullPointerException - 区分大小写:
"ABC".contains("abc")返回false - 空字符串
""是合法参数,且恒返回true(Java 规范定义空串是任意字符串的子串) - 只做字面量匹配,不支持通配符、正则语法或模糊搜索
安全调用:必须先判空
实际开发中,子串变量常来自用户输入或外部接口,可能为 null。直接调用 str.contains(sub) 风险极高。正确写法是:
sub != null && str.contains(sub)- 如果
str本身也可能为null,需前置判断:str != null && sub != null && str.contains(sub)
忽略大小写的替代方案
contains() 没有忽略大小写的重载版本。不要用 str.toLowerCase().contains(sub.toLowerCase()),原因有两个:
立即学习“Java免费学习笔记(深入)”;
- 非 ASCII 字符(如德语
ß、土耳其语I)在不同区域设置下转换结果不稳定 - 每次调用都创建新字符串,循环中性能损耗明显
推荐用 regionMatches() 手动实现:
public static boolean containsIgnoreCase(String str, String sub) {
if (str == null || sub == null) return false;
int len = sub.length();
if (len == 0) return true;
for (int i = 0; i <= str.length() - len; i++) {
if (str.regionMatches(true, i, sub, 0, len)) {
return true;
}
}
return false;
}性能与等价写法
str.contains(sub) 在 JDK 内部就是 str.indexOf(sub) >= 0 的封装,二者行为完全一致、性能无差别。如果已有代码在用 indexOf(),无需刻意改写;若追求语义清晰,优先选 contains()。
需要正则能力(如“以数字开头+下划线+字母”)时,contains() 不适用,应改用 Pattern.compile("...").matcher(str).find() 或 StringUtils.containsAny()(Apache Commons Lang)。


















