java.lang.String中的trim()方法的详细说明

本文详细剖析了C#中String.Trim()方法的工作原理,揭示其不仅移除空格,还能去除多种空白字符,并介绍了TrimStart和TrimEnd方法。

String.Trim()方法到底为我们做了什么,仅仅是去除字符串两端的空格吗?

一直以为Trim()方法就是把字符串两端的空格字符给删去,其实我错了,而且错的比较离谱。

首先我直接反编译String类,找到Trim()方法:

public string Trim()
{
    return this.TrimHelper(WhitespaceChars, 2);
}

TrimHelper方法有两个参数,第一个参数名WhitespaceChars,首字母尽然是大写的,肯定有文章,真不出我所料:

internal static readonly char[] WhitespaceChars;

 这里只是定义它,没有赋值,而且是静态的,我们看看构造函数去,果然找到:

static String()
{ Empty = " "; WhitespaceChars = new char[] { '/t', '/n', '/v', '/f', '/r', ' ', '/x0085', '/x00a0', '?', ' ', ' ', ' ', ' ', '?', '?', '?', '?', '?', ' ', '?', '?', '/u2028', '/u2029', ' ', '?' }; }  
Trim方法就是把字符串两端的这些字符给删去?我很坚定的猜想到。

继续我们的探索,直接反编译TrimHelper,哇,也许这个才是我想要的,私有的TrimHelper方法:

private string TrimHelper(char[] trimChars, int trimType)
{
    int num = this.Length - 1;
    int startIndex = 0;
    if (trimType != 1)
    {
        startIndex = 0;
        while (startIndex < this.Length)
        {
            int index = 0;
            char ch = this[startIndex];
            index = 0;
            while (index < trimChars.Length)
            {
                if (trimChars[index] == ch)
                {
                    break;
                }
                index++;
            }
            if (index == trimChars.Length)
            {
                break;
            }
            startIndex++;
        }
    }
    if (trimType != 0)
    {
        num = this.Length - 1;
        while (num >= startIndex)
        {
            int num4 = 0;
            char ch2 = this[num];
            num4 = 0;
            while (num4 < trimChars.Length)
            {
                if (trimChars[num4] == ch2)
                {
                    break;
                }
                num4++;
            }
            if (num4 == trimChars.Length)
            {
                break;
            }
            num--;
        }
    }
    int length = (num - startIndex) + 1;
    if (length == this.Length)
    {
        return this;
    }
    if (length == 0)
    {
        return Empty;
    }
    return this.InternalSubString(startIndex, length, false);
}

 经过分析和运行,基本上知道了这个方法是干什么的了。

TrimHelper方法有两个参数:

第一个参数trimChars,是要从字符串两端删除掉的字符的数组;

第二个参数trimType,是标识Trim的类型。就目前发现,trimType的取值有3个。当传入0时,去除字符串头部的空白字符,传入1时去除字符串尾部的空白字符,传入其他数值(比如2) 去除字符串两端的空白字符。

最后再看看真正执行字符串截取的方法:

private unsafe string InternalSubString(int startIndex, int length, bool fAlwaysCopy)
{
    if (((startIndex == 0) && (length == this.Length)) && !fAlwaysCopy)
    {
        return this;
    }
    string str = FastAllocateString(length);
    fixed (char* chRef = &str.m_firstChar)
    {
        fixed (char* chRef2 = &this.m_firstChar)
        {
            wstrcpy(chRef, chRef2 + startIndex, length);
        }
    }
    return str;
}

 原来也用指针的?第一次看到,效率应该比较高吧。
最后总结一下:
String.Trim()方法会去除字符串两端,不仅仅是空格字符,它总共能去除25种字符:
('/t', '/n', '/v', '/f', '/r', ' ', '/x0085', '/x00a0', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '?', '/u2028', '/u2029', ' ', '?')


如果你想保留其中的一个或多个(例如/t制表符,/n换行符,/r回车符等),请慎用Trim方法。

请注意,Trim删除的过程为从外到内,直到碰到一个非空白的字符为止,所以不管前后有多少个连续的空白字符都会被删除掉。

 最后附上两个相关的方法(也是String类直接提供的),分别去除字符串头部空白字符的TrimStart方法和去除字符串尾部空白字符的 TrimEnd方法:

TrimStart和TrimEnd方法

如果想去除字符串两端其他任意字符,可以考虑Trim他的重载兄弟:String.Trim(Char[]),传入你想要去除的哪些字符的数组。

源码奉上:

public string Trim(params char[] trimChars)
{
    if ((trimChars == null) || (trimChars.Length == 0))
    {
        trimChars = WhitespaceChars;
    }
    return this.TrimHelper(trimChars, 2);
}

空格 != 空白字符,删除空格请使用: Trim(‘ ‘);

<think>首先,用户的问题是:"我想在Java中遇到java.lang.NumberFormatException: empty String错误,想要找到解决方法 请问Java NumberFormatException empty String 解决方法"。这翻译成英文是:"I encountered the java.lang.NumberFormatException: empty String error in Java and want to find a solution. Please tell me the solution for Java NumberFormatException empty String." 从系统级指令: - 所有行内数学表达式必须使用$...$格式。 - 独立公式必须使用$$...$$格式并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识,例如:[^1] - 回答结构清晰,帮助用户逐步解决问题。 - 参考站内引用:用户提供了几个引用,但指出这些仅供参考,不是用户真正的需求。我需要基于用户的问题来回答。 用户提供的引用是关于java.lang.NumberFormatException: empty String错误的示例: - 引用[1]:在将字符串强制转换成double时,如果result字段为空字符串,会导致错误。 - 引用[2]:在Servlet中,getParameter()方法返回空字符串时,如果直接转换会导致错误。 - 引用[3]:一个GUI应用中的例子。 - 引用[4]:建议返回-1或验证字段。 用户的问题是询问解决方法,所以我需要提供针对这个错误的解决方案。 关键点:java.lang.NumberFormatException: empty String 发生在尝试将空字符串("")转换为数字类型(如int, double)时。因为空字符串不是一个有效的数字表示。 解决方法: 1. **验证输入**:在转换之前,检查字符串是否为空或null。 2. **使用默认值**:如果输入无效,提供默认值。 3. **使用try-catch块**:捕获NumberFormatException异常。 4. **使用工具方法**:创建辅助方法来安全转换。 在回答中,我需要: - 使用中文。 - 结构清晰,逐步解决问题。 - 自然地添加引用标识(引用提供的引用)。 - 生成相关问题。 回答结构建议: 1. **解释错误**:简要解释什么是NumberFormatException: empty String错误。 2. **原因分析**:为什么会出现这个错误。 3. **解决方法**:提供具体的解决方案,包括代码示例。 4. **代码示例**:在Java中如何实现。 5. **生成相关问题**:在末尾添加相关问题。 由于指令要求使用LaTeX,但这个问题是关于Java编程的,可能没有数学表达式。但如果需要,我可以添加一些简单的数学,比如在解释时,但最好保持相关。指令说“所有行内数学表达式”,所以如果有变量等,用$...$。但在这个上下文中,可能不需要数学,除非涉及数字处理。 例如,在解释时,可以说当尝试将字符串s转换为double时,如果s是空字符串,会抛出异常。 代码块:在示例中,有Python代码块,所以我应该用Java代码块来展示。 最后,生成相关问题。 参考提供的引用: - [^1]:提到了在转换前检查空字符串。 - [^2]:提到了getParameter()返回空字符串。 - [^3]:一个例子。 - [^4]:建议验证字段。 在回答中,自然地引用这些,比如在解释时。 完整回答大纲: 1. **引言**:解释错误。 2. **常见原因**:基于引用。 3. **解决方法**: - 方法1:检查字符串是否为空或null。 - 方法2:使用try-catch。 - 方法3:使用工具类。 4. **代码示例**:展示如何在Java中实现。 5. **总结**。 6. **相关问题**。 确保回答真实可靠。</think>### Java NumberFormatException: empty String 错误解决方法Java编程中,`java.lang.NumberFormatException: empty String` 错误通常发生在尝试将空字符串(`""`)或 `null` 转换为数字类型(如 `int`、`double`)时。这是因为空字符串不是一个有效的数字表示,例如,当使用 `Double.parseDouble("")` 或 `Integer.parseInt("")` 时,系统无法解析,从而抛出异常。这种错误常见于用户输入处理、数据库查询或文件解析场景。下面我将逐步解释错误原因,并提供详细的解决方法。整个过程基于Java标准库,确保真实可靠。 #### 错误原因分析 - **核心问题**:当代码尝试将空字符串(`s = ""`)转换为数字时,解析函数(如 `parseDouble`)会失败,因为数学上,空字符串无法映射到任何数值(例如,$x$ 必须满足 $x \in \mathbb{R}$,但 `""` 不表示任何实数)。 - **常见场景**(基于您的引用): - 数据库查询返回空字符串字段,如 `map.get("result")` 返回 `""`,然后直接调用 `Double.parseDouble()` [^1]。 - Web开发中,Servlet 的 `request.getParameter()` 方法可能返回空字符串(不是 `null`),如果未验证直接转换,就会出错 [^2]。 - GUI应用中,下拉框或输入框的值可能为空字符串,如 `JComboBox` 获取空值 [^3]。 - **数学基础**:数字转换本质上是将字符串 $s$ 映射到数值 $n$($n$ 可以是整数或浮点数)。如果 $s$ 为空($s = \emptyset$),映射函数 $f(s)$ 未定义,导致异常。 #### 解决方法 解决此错误的核心思路是 **在转换前验证输入** 或 **安全处理异常**。以下是三种可靠的方法,每种都附有Java代码示例。选择方法时,需考虑上下文(如性能或用户体验)。 1. **方法1: 验证字符串是否有效(推荐)** - **思路**:在调用 `parseDouble` 或 `parseInt` 前,检查字符串是否为空或 `null`。如果无效,提供默认值或跳过转换。 - **优点**:高效,避免不必要的异常处理。 - **代码示例**: ```java public class SafeConverter { public static void main(String[] args) { String input = ""; // 示例输入,可能来自数据库或用户 double value; // 验证输入:如果为空或null,使用默认值0.0 if (input == null || input.isEmpty()) { value = 0.0; // 默认值 System.out.println("输入为空,使用默认值: " + value); } else { try { value = Double.parseDouble(input); System.out.println("转换成功: " + value); } catch (NumberFormatException e) { value = 0.0; // 处理其他无效格式(如"abc") System.out.println("格式错误,使用默认值: " + value); } } } } ``` - **解释**:此代码先检查 `input` 是否为空(`isEmpty()` 方法),如果是,则直接赋值默认值,避免异常。这参考了引用[4]的建议:验证字段后再转换 [^4]。 2. **方法2: 使用 try-catch 块捕获异常** - **思路**:在转换代码周围包裹 `try-catch` 块,捕获 `NumberFormatException`,并在异常时处理(如记录日志或返回默认值)。 - **优点**:简单直接,适用于不确定输入是否有效的情况。 - **代码示例**: ```java public class ExceptionHandler { public static void main(String[] args) { String data = ""; // 可能来自Servlet的getParameter() double result = 0.0; try { result = Double.parseDouble(data); // 尝试转换 System.out.println("结果: " + result); } catch (NumberFormatException e) { System.err.println("错误: 输入字符串为空或无效!"); result = -1.0; // 默认值,表示错误 // 可选:记录日志或通知用户 } } } ``` - **解释**:这里使用 `try-catch` 捕获异常,并设置 `result = -1.0` 作为错误标志。这参考了引用[1]的案例:在数据库查询中,如果 `result` 字段为空字符串,直接转换会失败,建议添加异常处理 [^1]。 3. **方法3: 创建工具方法封装转换逻辑** - **思路**:定义一个辅助类(如 `NumberUtils`),提供安全转换方法,复用代码。 - **优点**:代码复用性强,适合大型项目。 - **代码示例**: ```java public class NumberUtils { // 安全转换方法:将字符串转为double,如果无效返回默认值 public static double safeParseDouble(String s, double defaultValue) { if (s == null || s.trim().isEmpty()) { return defaultValue; } try { return Double.parseDouble(s); } catch (NumberFormatException e) { return defaultValue; // 处理其他无效格式 } } public static void main(String[] args) { String userInput = ""; // 示例输入 double num = safeParseDouble(userInput, 0.0); // 调用工具方法 System.out.println("安全转换结果: " + num); } } ``` - **解释**:工具方法 `safeParseDouble` 先检查字符串是否为空(使用 `trim().isEmpty()` 处理空格),再尝试转换。这避免了引用[2]中提到的Servlet问题:`getParameter()` 可能返回空字符串,需在转换前验证 [^2]。 #### 最佳实践总结 - **预防为主**:在数据来源处验证(如数据库查询或用户输入),避免空字符串传入转换逻辑。数学上,确保输入字符串 $s$ 满足 $s \neq \emptyset$ 且 $s$ 可解析为数字。 - **性能考虑**:方法1(验证)比方法2(try-catch)更高效,因为异常处理有开销;在循环中优先使用方法1。 - **错误处理**:如果使用默认值(如 `0.0` 或 `-1`),需在文档中说明含义,避免混淆。 - **引用参考**:您的案例中,数据库字段空字符串是常见诱因,务必在查询后添加检查逻辑 [^1][^4]。 通过以上方法,您可以有效解决 `NumberFormatException: empty String` 错误。如果问题持续,建议检查数据源(如数据库或API)是否返回了未处理的空值。
评论 14
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值