я играл немного с изменением значения типа String (я знаю, что это крайне небезопасно и опасно) с функцией:«Изменчивый» Строка Java действует непредсказуемо
public static void reverse(String s) {
try {
Field val = String.class.getDeclaredField("value");
val.setAccessible(true);
char[] value = (char[]) val.get(s);
char[] inverse = s.toCharArray();
for (int i = 0; i < s.length(); i++)
value[i] = inverse[s.length()-i-1];
}
catch (Exception e) {
e.printStackTrace();
}
}
и через некоторое время я обнаружил, что в зависимости от Строковое создание действует крайне непредсказуемо. Я создал небольшой ум-игру с тем (так много отпечатков был необходим, чтобы получить желаемый эффект):
public static void main(String[] args) {
final String a = "abc";
final String b = new String("abc");
final String c = "abcd".substring(0, 3);
System.out.println("Let's start!");
System.out.print("a - ");
System.out.println(a);
System.out.print("b - ");
System.out.println(b);
System.out.print("c - ");
System.out.println(c);
System.out.print("Are they all equals? - ");
System.out.println(a.equals(b) && a.equals(c) && b.equals(c));
System.out.print("But they are different objects, right? - ");
System.out.println(!(a == b || b == c || a == c));
System.out.println("Let's reverse only 'a'. But all are final and String is not mutable, so what can go wrong?");
reverse(a);
System.out.println("Done. What we've got here?");
// trick 1
System.out.print("a = ");
System.out.print(a);
System.out.println(" - ok, 'a' is reversed. A bit strange, but it works. Super method");
System.out.print("b = ");
System.out.print(b);
System.out.println(" - wait... We haven't touched this");
System.out.print("c = ");
System.out.print(c);
System.out.println(" - this is untouched, wierd, huh? We've just reversed 'a' so 'b' and 'c' should act the same.");
// trick 2
System.out.println("\nOk, so 'c' should equals \"abc\", right?\n");
System.out.println("\"abc\".equals(c)? = "+"abc".equals(c));
System.out.println("...\n");
System.out.print("Do you remeber, that");
System.out.print(" a = ");
System.out.print(a);
System.out.print(" oraz b = ");
System.out.print(b);
System.out.println(" ?\n");
// trick 3
System.out.println("So let's check that");
System.out.print("a.equals(b) = ");
System.out.println(a.equals(b)+"\n");
System.out.println("Ok, we had expected that.\n");
System.out.println("But what do you think the result of (\" \"+a).equals(\" \"+b) will be?\n");
System.out.print("(\" \"+a).equals(\" \"+b) = ");
System.out.println((" "+a).equals(" "+b)+"\n");
System.out.print("And do you remeber, that");
System.out.print(" a = ");
System.out.print(a);
System.out.print(" ,a c = ");
System.out.print(c);
System.out.println(" ?\n");
// trick 4
System.out.println("So let's check if they are different:");
System.out.print("a.equals(c) = ");
System.out.println(a.equals(c));
System.out.println("So they are different... but are they really different?\n");
System.out.print("(\" \"+a).equals(\" \"+c) = ");
System.out.println((" "+a).equals(" "+c));
System.out.println("Booo!!! You could choose the blue pill!\n");
System.out.println("Our actors were: ");
System.out.print("a = ");
System.out.print(a);
System.out.print(", b = ");
System.out.print(b);
System.out.print(", c = ");
System.out.print(c);
System.out.print(" oraz abc = ");
System.out.println("abc");
System.out.print("\n");
// trick 5
System.out.println("Or in other words");
System.out.println("a = "+a+", b = "+b+", c = "+c+" oraz abc ="+(" "+"abc")+"\n");
System.out.println("But do you remember what we were revering? Was is rally b?");
System.out.println("Have a nice day. Z-DNA");
}
Но я не понимаю, что играть. Вся строка - это разные объекты, но с одинаковым значением.
Итак, почему в трюке 1 строка 'c' действовала иначе, чем 'b'?
Хорошо, я получаю трюк 2. «abc» больше не «abc», а «cba» (но почему? Я изменил значение String «a», а не значение пула строк), поэтому он не может быть равным «abc», но как «c» может быть «abc», когда я даже не могу получить «abc», вызывающий «abc» ??
Почему в трюке 3 после добавления пространства 'a' и 'b' больше не было равным и почему на земле в 4 'a' и 'c' с пробелами был равен?!?!
Trick 5 показывает нам, что значение 'a', 'b', 'c' и "abc" изменяется в зависимости от того, как мы его называем. (oh wait. 'c' является особенным. Самый нерациональный метод создания строки на самом деле наиболее невосприимчив к этой черной магии).
Пожалуйста, помогите мне понять, что я на самом деле сделал, а какая тьма - функция обратная.
Взгляните на этот ответ http://stackoverflow.com/questions/35899879/and-equals-not-working-in-android-studio-java/35899981 # 35899981 –
Здесь слишком много вопросов, и я не могу беспокоиться о них. Ответ на первый легко. 'new String (" abc ")' создает экземпляр 'new', но он разделяет * тот же * массив поддержки, что и' 'abc" '. –
Конечно, это непредсказуемо. Это _why._ –