endsWith() 方法详解:检查字符串是否以指定后缀结尾

方法定义

public boolean endsWith(String suffix)

功能说明

  • 检查字符串是否以指定的后缀结束
  • 区分大小写:大小写不同的字符视为不同
  • 后缀匹配:从字符串末尾开始比较
  • 空字符串("")作为后缀时总是返回 true
  • 后缀长度超过原字符串时返回 false

示例代码

public class EndsWithExample {
    public static void main(String[] args) {
        String file = "document.pdf";
        
        // 基本用法
        System.out.println(file.endsWith(".pdf"));   // true
        System.out.println(file.endsWith(".PDF"));   // false(大小写敏感)
        
        // 特殊情况
        System.out.println(file.endsWith(""));       // true(空后缀总是true)
        System.out.println(file.endsWith("document.pdf")); // true(完整匹配)
        
        // 路径检查
        String path = "/home/user/file.txt";
        System.out.println(path.endsWith("/"));      // false
        System.out.println(path.endsWith("file.txt")); // true
        
        // 超长后缀
        System.out.println("hello".endsWith("worldhello")); // false
    }
}

使用技巧

  1. 文件类型检查

    boolean isImage = fileName.endsWith(".jpg") 
                   || fileName.endsWith(".png");
    
  2. 路径验证

    if (!url.endsWith("/")) {
        url += "/"; // 确保URL以斜杠结尾
    }
    
  3. 域名验证

    boolean isValidDomain = domain.endsWith(".com") 
                         || domain.endsWith(".org");
    
  4. 结合 substring() 动态检查

    String dynamicSuffix = getFileExtension();
    if (file.endsWith(dynamicSuffix)) {
        // 处理特定后缀文件
    }
    

常见错误

  1. 忽略大小写敏感性

    // 错误:期待true但实际返回false
    "image.PNG".endsWith(".png"); // false
    

    解决方案:

    "image.PNG".toLowerCase().endsWith(".png"); // true
    
  2. 空指针异常

    String suffix = null;
    "test".endsWith(suffix); // 抛出NullPointerException
    
  3. 错误理解空后缀

    // 正确:空后缀总是返回true
    "any".endsWith(""); // true
    
  4. 混淆起始位置

    // 错误:试图检查开头而非结尾
    "file.txt".endsWith("file"); // false(应为startsWith)
    

注意事项

  1. 后缀匹配机制

    • 从原字符串末尾开始反向比较
    • 比较范围:[length()-suffix.length(), length()-1]
    • 内部实现等价于:
      startsWith(suffix, value.length - suffix.value.length)
      
  2. 空后缀行为

    • 任何字符串(包括空字符串)都以空后缀结尾
    • "".endsWith("") 返回 true
  3. Unicode 支持

    • 完全支持 Unicode 字符
    • 特殊字符(如 emoji)也能正确比较
      "hello😊".endsWith("😊"); // true
      

最佳实践与性能优化

  1. 空安全处理

    public static boolean safeEndsWith(String str, String suffix) {
        if (str == null || suffix == null) return false;
        return str.endsWith(suffix);
    }
    
  2. 性能优化

    • 短路检查:方法先检查后缀长度,超过立即返回 false
    • 长度缓存:JVM 会缓存字符串长度,无需担心重复计算
    • 避免不必要的字符串转换:
      // 优化前:每次调用创建新字符串
      fileName.toLowerCase().endsWith(".png");
      
      // 优化后:区域比较避免创建对象
      fileName.regionMatches(
          true, 
          fileName.length() - 4, 
          ".png", 
          0, 
          4
      );
      
  3. 批量检查优化

    // 高效检查多个后缀
    boolean hasValidSuffix(String file) {
        int len = file.length();
        return file.regionMatches(len-4, ".jpg", 0, 4)
            || file.regionMatches(len-4, ".png", 0, 4)
            || file.regionMatches(len-5, ".jpeg", 0, 5);
    }
    

总结

关键点 说明
核心功能 检查字符串是否以指定后缀结尾
大小写处理 区分大小写
空后缀行为 总是返回 true
时间复杂度 O(k)(k=后缀长度)
空指针风险 参数为 null 时抛出 NPE
适用场景 文件类型检查、路径验证、域名验证等

实践建议

✅ 文件操作时优先使用此方法进行扩展名检查
✅ 处理用户输入时结合 toLowerCase() 实现大小写不敏感检查
✅ 对性能敏感场景使用 regionMatches() 替代大小写转换
❌ 不要用于检查路径开头(用 startsWith()
❌ 避免传入 null 参数(使用空安全封装)

扩展知识

Java 11+ 中可用 String.isBlank() 结合 endsWith() 进行更复杂的后缀验证:

boolean isValid = !str.isBlank() && str.trim().endsWith(";");