-
Bug
-
Resolution: Fixed
-
P3
-
17
-
b25
-
Verified
A DESCRIPTION OF THE PROBLEM :
Explained in the attached test.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the attached test with --illegal-access=warn JVM option. The option is required for debugging purpose only.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
fooA.equals(fooB) == true
ACTUAL -
fooA.equals(fooB) == false
---------- BEGIN SOURCE ----------
import java.util.Arrays;
import java.util.Objects;
import java.util.StringJoiner;
/*
Run with "--illegal-access" option.
Example: java --illegal-access=warn Test.java
*/
public class Test {
public static void main(String[] args) throws Exception {
final String fooA = "foo";
// UTF-16 delimeter and Latin-1 element
// produces Latin-1 String with coder=UTF16
final String fooB = new StringJoiner("\u2013")
.add("foo")
.toString();
// fooA and fooB are should be equal (both are "foo"),
// but due to different "coder" field, the "equals" method returns false.
System.err.println(fooA.equals(fooB)); // prints false!
debugString("fooA", fooA);
debugString("fooB", fooB);
}
private static void debugString(String which, String s) throws Exception {
var coder = String.class.getDeclaredField("coder");
coder.setAccessible(true);
var value = String.class.getDeclaredField("value");
value.setAccessible(true);
System.err.println(which + ": string=\"" + s + "\" " +
"value=" + Arrays.toString((byte[])value.get(s)) +
" coder=" + coder.get(s)
);
}
}
---------- END SOURCE ----------
FREQUENCY : always
Explained in the attached test.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the attached test with --illegal-access=warn JVM option. The option is required for debugging purpose only.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
fooA.equals(fooB) == true
ACTUAL -
fooA.equals(fooB) == false
---------- BEGIN SOURCE ----------
import java.util.Arrays;
import java.util.Objects;
import java.util.StringJoiner;
/*
Run with "--illegal-access" option.
Example: java --illegal-access=warn Test.java
*/
public class Test {
public static void main(String[] args) throws Exception {
final String fooA = "foo";
// UTF-16 delimeter and Latin-1 element
// produces Latin-1 String with coder=UTF16
final String fooB = new StringJoiner("\u2013")
.add("foo")
.toString();
// fooA and fooB are should be equal (both are "foo"),
// but due to different "coder" field, the "equals" method returns false.
System.err.println(fooA.equals(fooB)); // prints false!
debugString("fooA", fooA);
debugString("fooB", fooB);
}
private static void debugString(String which, String s) throws Exception {
var coder = String.class.getDeclaredField("coder");
coder.setAccessible(true);
var value = String.class.getDeclaredField("value");
value.setAccessible(true);
System.err.println(which + ": string=\"" + s + "\" " +
"value=" + Arrays.toString((byte[])value.get(s)) +
" coder=" + coder.get(s)
);
}
}
---------- END SOURCE ----------
FREQUENCY : always