Android Bug?:String.substring(5).replace(“”,“”)空字符串

Android Bug?:String.substring(5).replace(“”,“”)空字符串,第1张

Android Bug?:String.substring(5).replace(“”,“”)//空字符串 答对了!我发现了这个错误

感谢@izht提供源代码的链接。我已找到有关此问题的错误。

仅当String的后备数组具有与实际String不同(更长)的值时,才会发生这种情况。特别是

String.offset
(私有变量)大于零时。

解决方法是:

public String replace(CharSequence target, CharSequence replacement) {    if (target == null) {        throw new NullPointerException("target == null");    }    if (replacement == null) {        throw new NullPointerException("replacement == null");    }    String targetString = target.toString();    int matchStart = indexOf(targetString, 0);    if (matchStart == -1) {        // If there's nothing to replace, return the original string untouched.        return this;    }    String replacementString = replacement.toString();    // The empty target matches at the start and end and between each character.    int targetLength = targetString.length();    if (targetLength == 0) {        int resultLength = (count + 2) * replacementString.length();        StringBuilder result = new StringBuilder(resultLength);        result.append(replacementString);//        for (int i = offset; i < count; ++i) {  // original, bug        for (int i = offset; i < (count + offset); ++i) {    // fix result.append(value[i]); result.append(replacementString);        }        return result.toString();    }    StringBuilder result = new StringBuilder(count);    int searchStart = 0;    do {        // Copy characters before the match...        result.append(value, offset + searchStart, matchStart - searchStart);        // Insert the replacement...        result.append(replacementString);        // And skip over the match...        searchStart = matchStart + targetLength;    } while ((matchStart = indexOf(targetString, searchStart)) != -1);    // Copy any trailing chars...    result.append(value, offset + searchStart, count - searchStart);    return result.toString();}

我不确定为什么Android必须以

replace()
这种方式更改(并错误地更改)。原始的Java实现没有此问题。

顺便说一下, 现在是什么? 我该怎么办?(除了

replace()
格外小心使用,或丢弃我的Android手机:-/)


顺便说一句,我很确定我的LG E720 Optimus Chic(Android
2.2)使用的源代码与此不同。在目标字符串

String.replace()

空的情况下, 它会继续停止(可疑无限循环)。最近我发现它抛出此错误消息:

05-10 16:41:13.155: E/AndroidRuntime(9384): FATAL EXCEPTION: main05-10 16:41:13.155: E/AndroidRuntime(9384): java.lang.OutOfMemoryError05-10 16:41:13.155: E/AndroidRuntime(9384):   at java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:97)05-10 16:41:13.155: E/AndroidRuntime(9384):   at java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:157)05-10 16:41:13.155: E/AndroidRuntime(9384):   at java.lang.StringBuilder.append(StringBuilder.java:217)05-10 16:41:13.155: E/AndroidRuntime(9384):   at java.lang.String.replace(String.java:1497)05-10 16:41:13.155: E/AndroidRuntime(9384):   at com.example.testprojectnew.MainActivity.onCreate(MainActivity.java:22)05-10 16:41:13.155: E/AndroidRuntime(9384):   at android.app.Instrumentation.callActivityonCreate(Instrumentation.java:1047)05-10 16:41:13.155: E/AndroidRuntime(9384):   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)05-10 16:41:13.155: E/AndroidRuntime(9384):   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)05-10 16:41:13.155: E/AndroidRuntime(9384):   at android.app.ActivityThread.access00(ActivityThread.java:125)05-10 16:41:13.155: E/AndroidRuntime(9384):   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)05-10 16:41:13.155: E/AndroidRuntime(9384):   at android.os.Handler.dispatchMessage(Handler.java:99)05-10 16:41:13.155: E/AndroidRuntime(9384):   at android.os.Looper.loop(Looper.java:123)05-10 16:41:13.155: E/AndroidRuntime(9384):   at android.app.ActivityThread.main(ActivityThread.java:4627)05-10 16:41:13.155: E/AndroidRuntime(9384):   at java.lang.reflect.Method.invokeNative(Native Method)05-10 16:41:13.155: E/AndroidRuntime(9384):   at java.lang.reflect.Method.invoke(Method.java:521)05-10 16:41:13.155: E/AndroidRuntime(9384):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:878)05-10 16:41:13.155: E/AndroidRuntime(9384):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:636)05-10 16:41:13.155: E/AndroidRuntime(9384):   at dalvik.system.NativeStart.main(Native Method)

仔细考虑一下,如果那个for循环的东西 bug。这应该是一个编译时问题。为什么在不同的手机(不同版本的Android)中,它的行为会有所不同?


完整的解决方法

获得了 Google
的更新,他们已经对其进行了修补,并将在以后的版本中进行更正。

同时,我根据他们的代码编写了一个修补方法:

(这是必要的,因为(1)我们仍然必须等待正确的发布,(2)我们需要照顾没有进行该固定更新的设备)

public static String replacePatched(final String string, final CharSequence target, final CharSequence replacement) {    if (target == null) {        throw new NullPointerException("target == null");    }    if (replacement == null) {        throw new NullPointerException("replacement == null");    }    final String targetString = target.toString();    int matchStart = string.indexOf(targetString, 0);    if (matchStart == -1) {        // If there's nothing to replace, return the original string untouched.        return new String(string);    }    final char[] value = string.toCharArray();        // required in patch    final int count = value.length;        // required in patch    final String replacementString = replacement.toString();    // The empty target matches at the start and end and between each character.    if (targetString.length() == 0) {        // The result contains the original 'count' characters, a copy of the        // replacement string before every one of those characters, and a final        // copy of the replacement string at the end.        final StringBuilder result = new StringBuilder(count + (count + 1) * replacementString.length());        result.append(replacementString);        for (int i = 0; i < count; ++i) { result.append(value[i]); result.append(replacementString);        }        return new String(result);      // StringBuilder.toString() does not give exact length    }    final StringBuilder result = new StringBuilder(count);    int searchStart = 0;    do {        // Copy characters before the match...        result.append(value, searchStart, matchStart - searchStart);        // Insert the replacement...        result.append(replacementString);        // And skip over the match...        searchStart = matchStart + targetString.length();    } while ((matchStart = string.indexOf(targetString, searchStart)) != -1);    // Copy any trailing chars...    result.append(value, searchStart, count - searchStart);    return new String(result);          // StringBuilder.toString() does not give exact length}

详细版本:

public static String replacePatched(final String string, final CharSequence target, final CharSequence replacement) {    if (target == null) {        throw new NullPointerException("target == null");    }    if (replacement == null) {        throw new NullPointerException("replacement == null");    }//    String targetString = target.toString();   // original    final String targetString = target.toString();//    int matchStart = indexOf(targetString, 0); // original    int matchStart = string.indexOf(targetString, 0);    if (matchStart == -1) {        // If there's nothing to replace, return the original string untouched.//        return this;     // original        return new String(string);    }    final char[] value = string.toCharArray();        // required in patch    final int count = value.length;        // required in patch//    String replacementString = replacement.toString();    // original    final String replacementString = replacement.toString();    // The empty target matches at the start and end and between each character.//    int targetLength = targetString.length();  // original//    if (targetLength == 0) {        // original    if (targetString.length() == 0) {//        int resultLength = (count + 2) * replacementString.length(); // original//        // The result contains the original 'count' characters, a copy of the//        // replacement string before every one of those characters, and a final//        // copy of the replacement string at the end.//        int resultLength = count + (count + 1) * replacementString.length();    // patched by Google Android//        StringBuilder result = new StringBuilder(resultLength);      // original        final StringBuilder result = new StringBuilder(count + (count + 1) * replacementString.length());        result.append(replacementString);//        for (int i = offset; i < count; ++i) { // original//        int end = offset + count;   // patched by Google Android//        for (int i = offset; i != end; ++i) {  // patched by Google Android        for (int i = 0; i < count; ++i) { result.append(value[i]); result.append(replacementString);        }//        return result.toString();   // original        return new String(result);      // StringBuilder.toString() does not give exact length    }//    StringBuilder result = new StringBuilder(count);      // original    final StringBuilder result = new StringBuilder(count);    int searchStart = 0;    do {        // Copy characters before the match...//        result.append(value, offset + searchStart, matchStart - searchStart);   // original        result.append(value, searchStart, matchStart - searchStart);        // Insert the replacement...        result.append(replacementString);        // And skip over the match...//        searchStart = matchStart + targetLength;          // original        searchStart = matchStart + targetString.length();//    } while ((matchStart = indexOf(targetString, searchStart)) != -1);          // original    } while ((matchStart = string.indexOf(targetString, searchStart)) != -1);    // Copy any trailing chars...//    result.append(value, offset + searchStart, count - searchStart); // original    result.append(value, searchStart, count - searchStart);//    return result.toString();       // original    return new String(result);          // StringBuilder.toString() does not give exact length}


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5428850.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-11
下一篇 2022-12-11

发表评论

登录后才能评论

评论列表(0条)

保存