{"id":9557,"date":"2020-03-11T09:00:49","date_gmt":"2020-03-11T08:00:49","guid":{"rendered":"https:\/\/www.happycoders.eu\/?p=9557"},"modified":"2025-06-12T08:37:41","modified_gmt":"2025-06-12T06:37:41","slug":"deep-reflection-integer-string-modifizieren","status":"publish","type":"post","link":"https:\/\/www.happycoders.eu\/de\/java\/deep-reflection-integer-string-modifizieren\/","title":{"rendered":"Java Deep Reflection: Wie man Integer und String hackt"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Ich lese gerade das Buch \"<a href=\"https:\/\/www.amazon.de\/gp\/product\/020161622X\/ref=as_li_qf_asin_il_tl?ie=UTF8&amp;tag=happycoders07-21&amp;creative=6742&amp;linkCode=as2&amp;creativeASIN=020161622X&amp;linkId=e24d894336bfeb531adca6f6ab18b952\" target=\"_blank\" rel=\"noopener\">The Pragmatic Programmer<\/a>\" von Andrew Hunt und David Thomas. Darin stellen die Autoren folgende Aufgabe: <\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Which of these \"impossible\" things can happen?<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">[\u2026]<br>3. In C++:<code>  a = 2; b = 3; if (a + b != 5) exit(1);<\/code><br> [\u2026]<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Eine der richtigen Antworten ist 3. In C++ gibt es mehrere Gr\u00fcnde, warum die Bedingung \"<code>a + b != 5<\/code>\" erf\u00fcllt sein k\u00f6nnte:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Operator Overloading: z. B. kann man den '+'-Operator eine Multiplikation ausf\u00fchren lassen.<\/li>\n\n\n\n<li>Variable Aliasing: <code>b<\/code> ist ein Alias f\u00fcr <code>a<\/code>, damit setzt die Zuweisung <code>b = 3<\/code> auch <code>a<\/code> auf 3, und die Summe ist 6.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Da es beides in Java nicht gibt, habe ich mich gefragt: Kann ich denselben Code auch in Java so schreiben, dass die Bedingung erf\u00fcllt ist? Die Antwort lautet: ja. Wie das m\u00f6glich ist, erf\u00e4hrst du in diesem Artikel.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Die Code-Beispiele des Artikels findest du in meinem <a rel=\"noopener\" href=\"https:\/\/github.com\/SvenWoltmann\/deep-reflection\" target=\"_blank\">GitHub-Repository<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"2-3-5\">2 + 3 = 5<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Fangen wir ganz einfach an: mit einer <code>main<\/code>-Funktion, in der zwei primitive ints, <code>a<\/code> und <code>b<\/code>, deklariert werden, gefolgt vom zu testenden Code:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">import<\/span> <span class=\"hljs-keyword\">static<\/span> java.lang.System.exit;\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">ImpossibleThings1<\/span> <\/span>{\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">(String&#091;] args)<\/span> <\/span>{\n    <span class=\"hljs-keyword\">int<\/span> a, b;\n    a = <span class=\"hljs-number\">2<\/span>; b = <span class=\"hljs-number\">3<\/span>; <span class=\"hljs-keyword\">if<\/span> (a + b != <span class=\"hljs-number\">5<\/span>) exit(<span class=\"hljs-number\">1<\/span>);\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Selbstverst\u00e4ndlich gilt hier a + b = 5, so dass das Programm regul\u00e4r, also mit Exit-Code 0, endet.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"2-3-6-deep-reflection-mit-integer\">2 + 3 = 6: Deep Reflection mit Integer<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Mit einer gar nicht allzu gro\u00dfen \u00c4nderung k\u00f6nnen wir daf\u00fcr sorgen, dass die Bedingung wahr wird (also, dass 2 + 3 <em>nicht<\/em> 5 ist) und das Programm mit Fehlercode 1 endet:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">ImpossibleThings2<\/span> <\/span>{\n  <span class=\"hljs-keyword\">static<\/span> {\n    <span class=\"hljs-keyword\">try<\/span> {\n      Field VALUE = Integer<span class=\"hljs-class\">.<span class=\"hljs-keyword\">class<\/span>.<span class=\"hljs-title\">getDeclaredField<\/span>(\"<span class=\"hljs-title\">value<\/span>\")<\/span>;\n      VALUE.setAccessible(<span class=\"hljs-keyword\">true<\/span>);\n      VALUE.set(<span class=\"hljs-number\">2<\/span>, <span class=\"hljs-number\">3<\/span>);\n    } <span class=\"hljs-keyword\">catch<\/span> (ReflectiveOperationException e) {\n      <span class=\"hljs-keyword\">throw<\/span> <span class=\"hljs-keyword\">new<\/span> Error(e);\n    }\n  }\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">(String&#091;] args)<\/span> <\/span>{\n    Integer a, b;\n    a = <span class=\"hljs-number\">2<\/span>; b = <span class=\"hljs-number\">3<\/span>; <span class=\"hljs-keyword\">if<\/span> (a + b != <span class=\"hljs-number\">5<\/span>) exit(<span class=\"hljs-number\">1<\/span>);\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Hier ist der Beweis:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full_800\"><img decoding=\"async\" width=\"800\" height=\"160\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_integer_deep_reflection_magic_v3-800x160.png\" alt=\"Screenshot mit der Ausgabe &quot;exit code 1&quot;\" class=\"wp-image-10356\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_integer_deep_reflection_magic_v3-800x160.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_integer_deep_reflection_magic_v3-224x45.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_integer_deep_reflection_magic_v3-336x67.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_integer_deep_reflection_magic_v3-504x101.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_integer_deep_reflection_magic_v3-672x134.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_integer_deep_reflection_magic_v3-400x80.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_integer_deep_reflection_magic_v3-600x120.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_integer_deep_reflection_magic_v3.png 891w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><figcaption class=\"wp-element-caption\">Screenshot mit der Ausgabe \"exit code 1\"<\/figcaption><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">Was haben wir getan? Wir verwenden hier <code>Integer<\/code> statt <code>int<\/code> und machen von reichlich Auto-Boxing und -Unboxing Gebrauch. Was hier genau passiert, beschreibe ich im n\u00e4chsten Abschnitt.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"auto-unboxing-aufgedeckt\">Auto-(un)boxing aufgedeckt<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Im Folgenden habe ich Auto-Boxing und -Unboxing durch explizites Boxing und Unboxing ersetzt. So wird deutlicher, was passiert. Die \u00c4nderungen sind gelb markiert (um dies zu erm\u00f6glichen, musste ich hier ein einfache Textbox verwenden).<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>public class <\/strong>ImpossibleThings3 {\n  <strong>static <\/strong>{\n    <strong>try <\/strong>{\n      Field VALUE = Integer.<strong>class<\/strong>.getDeclaredField(<strong>\"value\"<\/strong>);\n      VALUE.setAccessible(<strong>true<\/strong>);\n      <span style=\"background:#FFD567\">Integer two = Integer.<em>valueOf<\/em>(<\/span>2<span style=\"background:#FFD567\">)<\/span>;\n      VALUE.set(<span style=\"background:#FFD567\">two<\/span>, 3);\n    } <strong>catch <\/strong>(ReflectiveOperationException e) {\n      <strong>throw new <\/strong>Error(e);\n    }\n  }\n\n  <strong>public static void <\/strong>main(String[] args) {\n    Integer a, b;\n    a = <span style=\"background:#FFD567\">Integer.<em>valueOf<\/em>(<\/span>2<span style=\"background:#FFD567\">)<\/span>;\n    b = <span style=\"background:#FFD567\">Integer.<em>valueOf<\/em>(<\/span>3<span style=\"background:#FFD567\">)<\/span>;\n    <strong>if <\/strong>(a<span style=\"background:#FFD567\">.intValue()<\/span> + b<span style=\"background:#FFD567\">.intValue()<\/span> != 5) <em>exit<\/em>(1);\n  }\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>Integer.valueOf()<\/code> liefert f\u00fcr die Werte -128 to 127 gecachte Integer-Instanzen zur\u00fcck.*<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ein Integer-Objekt speichert den eigentlichen Wert in einem privaten <code>value<\/code>-Feld und gibt eben diesen \u00fcber <code>intValue()<\/code> zur\u00fcck.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Im statischen Initializer holen wir uns das gecachten Integer-Objekt f\u00fcr den Wert 2. Mittels Deep Reflection setzen wir dessen <code>value<\/code> auf die Zahl 3. Da <code>value<\/code> ein privates Feld ist, m\u00fcssen wir den Zugriff darauf mit <code>Field.setAccessible(true)<\/code> zun\u00e4chst gestatten.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">W\u00fcrden wir nun mit <code>System.out.println(two)<\/code> dieses Objekt ausgeben, w\u00fcrden wir diese \"3\" sehen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In der main-Methode wird <code>a = 2<\/code> zu <code>a = Integer.valueOf(2)<\/code> geboxt, was wiederum dieselbe gecachte Integer-Instanz liefert wie <code>two<\/code>, dessen Wert mittlerweile 3 ist. <code>b<\/code> ist ebenfalls 3 und somit ergibt <code>a + b<\/code> an dieser Stelle 6. Und das ist bekannterma\u00dfen ungleich 5 (sofern diese nicht auch \"gehackt\" wurde ... was aber meines Wissens nach bei einem int-Primitiv nicht m\u00f6glich ist) .<\/p>\n\n\n\n<p style=\"font-size:80%\">(*Garantiert ist dieses Verhalten nicht, aber praktisch ist es so. Mit <code>-XX:AutoBoxCacheMax<\/code> kann der gecachte Integer-Bereich vergr\u00f6\u00dfert werden.)<\/p>\n\n\n<div class=\"convertkit-form wp-block-convertkit-form\" style=\"\"><script async data-uid=\"1427197203\" src=\"https:\/\/happycoders.kit.com\/1427197203\/index.js\" data-jetpack-boost=\"ignore\" data-no-defer=\"1\" data-no-optimize=\"1\" nowprocket><\/script><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"deep-reflection-mit-strings\">Deep Reflection mit Strings<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Dasselbe l\u00e4sst sich auch mit Strings machen. Die folgenden Beispiele funktionieren so <strong>ab Java 9<\/strong>, eine Anpassung f\u00fcr \u00e4ltere Versionen folgt <a href=\"#String-Repraesentation_byte_vs_char\">weiter unten<\/a>.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">ImpossibleThings4<\/span> <\/span>{\n  <span class=\"hljs-keyword\">static<\/span> {\n    <span class=\"hljs-keyword\">try<\/span> {\n      Field VALUE = String<span class=\"hljs-class\">.<span class=\"hljs-keyword\">class<\/span>.<span class=\"hljs-title\">getDeclaredField<\/span>(\"<span class=\"hljs-title\">value<\/span>\")<\/span>;\n      VALUE.setAccessible(<span class=\"hljs-keyword\">true<\/span>);\n      VALUE.set(<span class=\"hljs-string\">\"Hello world\"<\/span>, <span class=\"hljs-string\">\"You have been hacked\"<\/span>.getBytes());\n    } <span class=\"hljs-keyword\">catch<\/span> (ReflectiveOperationException e) {\n      <span class=\"hljs-keyword\">throw<\/span> <span class=\"hljs-keyword\">new<\/span> Error(e);\n    }\n  }\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">(String&#091;] args)<\/span> <\/span>{\n    System.out.println(<span class=\"hljs-string\">\"Hello world\"<\/span>);\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Die Ausgabe dieses Programms lautet \"You have been hacked\". Hier der Beweis:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full_800\"><img decoding=\"async\" width=\"800\" height=\"176\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_v2-800x176.png\" alt=\"Screenshot mit der Ausgabe von &quot;You have been hackend&quot;\" class=\"wp-image-10357\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_v2-800x176.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_v2-224x49.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_v2-336x74.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_v2-504x111.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_v2-672x148.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_v2-400x88.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_v2-600x132.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_v2.png 891w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><figcaption class=\"wp-element-caption\">Screenshot mit der Ausgabe von \"You have been hackend\"<\/figcaption><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">So einfach, wie es in diesem Beispiel scheint, funktioniert es allerdings nicht immer. In\u00adwie\u00adweit wir Strings mit Deep Reflection manipulieren k\u00f6nnen, h\u00e4ngt von drei Faktoren ab:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>ob Strings als Konstanten vorliegen oder zur Laufzeit erstellt werden,<\/li>\n\n\n\n<li>ob Strings Sonderzeichen enthalten, die nicht als Latin-1 kodiert werden k\u00f6nnen,<\/li>\n\n\n\n<li>welche Java-Version wir verwenden.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"strings-muessen-als-konstanten-vorliegen\">Strings m\u00fcssen als Konstanten vorliegen<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Zun\u00e4chst einmal m\u00fcssen Strings als Kontanten im Code enthalten sein. Nur String-Konstanten werden, wenn sie gleich sind, durch dieselbe Objektreferenz ersetzt.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Folgendes funktioniert noch:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">ImpossibleThings5<\/span> <\/span>{\n  <span class=\"hljs-keyword\">static<\/span> { ... }\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">(String&#091;] args)<\/span> <\/span>{\n    System.out.println(<span class=\"hljs-string\">\"Hello\"<\/span> + <span class=\"hljs-string\">\" \"<\/span> + <span class=\"hljs-string\">\"world\"<\/span>);\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Hier f\u00fcgt bereits der Compiler die drei Teile zu einem einzigen String zusammen \u2013 zur Laufzeit ist das dann derselbe String wie der, dessen <code>value<\/code>-Inhalt wir \u00e4ndern.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Folgendes hingegen funktioniert nicht:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">ImpossibleThings6<\/span> <\/span>{\n  <span class=\"hljs-keyword\">static<\/span> { ... }\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">(String&#091;] args)<\/span> <\/span>{\n    System.out.println(<span class=\"hljs-string\">\"Hello \"<\/span> + getName());\n  }\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> String <span class=\"hljs-title\">getName<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-string\">\"world\"<\/span>;\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Hier werden erst zur Laufzeit \"Hello \" und \"world\" verkettet. Dabei entsteht ein neues String-Objekt mit dem <code>value<\/code>-Inhalt \"Hello world\".<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Vergleich der Objekt-Identit\u00e4ten<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Etwas klarer wird es, wenn wir uns die Identit\u00e4ten der String-Objekte anschauen, hier noch einmal am ersten String-Beispiel:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">ImpossibleThings4WithIdentity<\/span> <\/span>{\n  <span class=\"hljs-keyword\">static<\/span> {\n    <span class=\"hljs-keyword\">try<\/span> {\n      Field VALUE = String<span class=\"hljs-class\">.<span class=\"hljs-keyword\">class<\/span>.<span class=\"hljs-title\">getDeclaredField<\/span>(\"<span class=\"hljs-title\">value<\/span>\")<\/span>;\n      VALUE.setAccessible(<span class=\"hljs-keyword\">true<\/span>);\n      String s1 = <span class=\"hljs-string\">\"Hello world\"<\/span>;\n      System.out.println(<span class=\"hljs-string\">\"identityHashCode(s1) = \"<\/span> + System.identityHashCode(s1));\n      VALUE.set(s1, <span class=\"hljs-string\">\"You have been hacked\"<\/span>.getBytes());\n    } <span class=\"hljs-keyword\">catch<\/span> (ReflectiveOperationException e) {\n      <span class=\"hljs-keyword\">throw<\/span> <span class=\"hljs-keyword\">new<\/span> Error(e);\n    }\n  }\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">(String&#091;] args)<\/span> <\/span>{\n    String s2 = <span class=\"hljs-string\">\"Hello world\"<\/span>;\n    System.out.println(<span class=\"hljs-string\">\"identityHashCode(s2) = \"<\/span> + System.identityHashCode(s2));\n    System.out.println(s2);\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Die Ausgabe lautet:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full_800\"><img decoding=\"async\" width=\"800\" height=\"208\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_id1-800x208.png\" alt=\"Screenshot mit Anzeige der Objekt-Identit\u00e4ten\" class=\"wp-image-10359\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_id1-800x208.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_id1-224x58.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_id1-336x87.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_id1-504x131.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_id1-672x175.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_id1-400x104.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_id1-600x156.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_id1.png 891w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><figcaption class=\"wp-element-caption\">Screenshot mit Anzeige der Objekt-Identit\u00e4ten<\/figcaption><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">Das String-Objekt <code>s1<\/code>, das wir im statischen Initialisierer modifizieren, ist also identisch* zum String-Objekt <code>s2<\/code>, das wir in der <code>main<\/code>-Methode ausgeben. Wir geben also genau den String aus, den wir per Deep Reflection ver\u00e4ndert haben.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Dasselbe pr\u00fcfen wir noch einmal f\u00fcr den String, der im Quellcode aus String-Konstanten verkettet wird:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">ImpossibleThings5WithIdentity<\/span> <\/span>{\n  <span class=\"hljs-keyword\">static<\/span> { ... }\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">(String&#091;] args)<\/span> <\/span>{\n    String s2 = <span class=\"hljs-string\">\"Hello\"<\/span> + <span class=\"hljs-string\">\" \"<\/span> + <span class=\"hljs-string\">\"world\"<\/span>;\n    System.out.println(<span class=\"hljs-string\">\"identityHashCode(s2) = \"<\/span> + System.identityHashCode(s2));\n    System.out.println(s2);\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Wir erhalten folgende Ausgabe:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full_800\"><img decoding=\"async\" width=\"800\" height=\"208\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_id2-800x208.png\" alt=\"Screenshot mit Anzeige der Objekt-Identit\u00e4ten\" class=\"wp-image-10360\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_id2-800x208.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_id2-224x58.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_id2-336x87.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_id2-504x131.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_id2-672x175.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_id2-400x104.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_id2-600x156.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_id2.png 891w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><figcaption class=\"wp-element-caption\">Screenshot mit Anzeige der Objekt-Identit\u00e4ten<\/figcaption><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">Auch bei diesem Beispeil sind die String-Objekte <code>s1<\/code> und <code>s2<\/code> identisch.*<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Und zuletzt \u00fcberpr\u00fcfen wir die Objekt-Identit\u00e4ten bei der dritten Variante, bei der ein Teil des Strings durch eine Methode zur\u00fcckgeliefert wird:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">ImpossibleThings6WithIdentity<\/span> <\/span>{\n  <span class=\"hljs-keyword\">static<\/span> { ... }\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">(String&#091;] args)<\/span> <\/span>{\n    String s2 = <span class=\"hljs-string\">\"Hello \"<\/span> + getName();\n    System.out.println(<span class=\"hljs-string\">\"identityHashCode(s2) = \"<\/span> + System.identityHashCode(s2));\n    System.out.println(s2);\n  }\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">static<\/span> String <span class=\"hljs-title\">getName<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-string\">\"world\"<\/span>;\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Hier die Ausgabe des dritten Tests:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full_800\"><img decoding=\"async\" width=\"800\" height=\"208\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_id3-800x208.png\" alt=\"Screenshot mit Anzeige der Objekt-Identit\u00e4ten\" class=\"wp-image-10361\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_id3-800x208.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_id3-224x58.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_id3-336x87.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_id3-504x131.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_id3-672x175.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_id3-400x104.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_id3-600x156.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_id3.png 891w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><figcaption class=\"wp-element-caption\">Screenshot mit Anzeige der Objekt-Identit\u00e4ten<\/figcaption><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">Wir haben also die Best\u00e4tigung, dass es sich bei <code>s1<\/code> und <code>s2<\/code> um zwei unterschiedliche String-Objekte handelt. Die \u00c4nderung von <code>s1<\/code> per Reflection wirkt sich daher nicht auf <code>s2<\/code> aus.<\/p>\n\n\n\n<p style=\"font-size:80%\">(* Auch zwei nicht-identische Objekte k\u00f6nnten denselben Identity-HashCode haben. Wir m\u00fcssten eigentlich noch mit <code>s1 == s2<\/code> die Identit\u00e4t \u00fcberpr\u00fcfen. Die Wahrscheinlichkeit daf\u00fcr ist allerdings minimal, so dass mir f\u00fcr die Beispiele der Vergleich der HashCodes gen\u00fcgt.)<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"string-repraesentation-latin-1-vs-utf-16\">String-Repr\u00e4sentation: Latin-1 vs. UTF-16<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Wenn wir das erste String-Beispiel leicht ab\u00e4ndern, kommt ein zun\u00e4chst ziemlich unerwartetes Ergebnis heraus. Wir \u00e4ndern den auszugebenen String von \"Hello world\" in \"Hello world \u2713\" (mit einem H\u00e4kchen am Ende):<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">ImpossibleThings7<\/span> <\/span>{\n  <span class=\"hljs-keyword\">static<\/span> {\n    <span class=\"hljs-keyword\">try<\/span> {\n      Field VALUE = String<span class=\"hljs-class\">.<span class=\"hljs-keyword\">class<\/span>.<span class=\"hljs-title\">getDeclaredField<\/span>(\"<span class=\"hljs-title\">value<\/span>\")<\/span>;\n      VALUE.setAccessible(<span class=\"hljs-keyword\">true<\/span>);\n      VALUE.set(<span class=\"hljs-string\">\"Hello world \u2713\"<\/span>, <span class=\"hljs-string\">\"You have been hacked\"<\/span>.getBytes());\n    } <span class=\"hljs-keyword\">catch<\/span> (ReflectiveOperationException e) {\n      <span class=\"hljs-keyword\">throw<\/span> <span class=\"hljs-keyword\">new<\/span> Error(e);\n    }\n  }\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">(String&#091;] args)<\/span> <\/span>{\n    System.out.println(<span class=\"hljs-string\">\"Hello world \u2713\"<\/span>);\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Was wird hier ausgegeben? Was denkst du? (Wir sind immer noch bei Java 9 oder h\u00f6her.)<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\"Hello world \u2713\"<\/li>\n\n\n\n<li>\"You have been hacked\"<\/li>\n\n\n\n<li>\"You have been hacked \u2713\"<\/li>\n\n\n\n<li>\"\u6f59\u2075\u6168\u6576\u6220\u6565\u206e\u6168\u6b63\u6465\"<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Die Antwort findest du in folgendem Screenshot:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full_800\"><img decoding=\"async\" width=\"800\" height=\"176\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_chinese-800x176.png\" alt=\"Screenshot mit der Ausgabe chinesischer Zeichen\" class=\"wp-image-10365\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_chinese-800x176.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_chinese-224x49.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_chinese-336x74.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_chinese-504x111.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_chinese-672x148.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_chinese-400x88.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_chinese-600x132.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_chinese.png 891w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><figcaption class=\"wp-element-caption\">Screenshot mit der Ausgabe chinesischer Zeichen<\/figcaption><\/figure>\n<\/div>\n\n\n<h4 class=\"wp-block-heading\">Wie l\u00e4sst sich das erkl\u00e4ren?<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Dazu m\u00fcssen wir uns die interne Repr\u00e4sentation eines Strings anschauen. Seit Java 9 wird ein String intern als <code>byte[]<\/code> dargestellt. Die Art der Kodierung von Characters in Bytes h\u00e4ngt dabei davon ab, ob der String ausschlie\u00dflich Latin-1-kodierbare Zeichen enth\u00e4lt oder auch andere. Enth\u00e4lt der String nur Zeichen, die in Latin-1 kodiert werden k\u00f6nnen, wird pro Zeichen genau ein Byte verwendet. Enth\u00e4lt der String jedoch auch andere Zeichen, wird er als UTF-16 kodiert. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Dieses Feature nennt sich \"String Compaction\", wurde im <a rel=\"noopener\" href=\"https:\/\/openjdk.org:443\/jeps\/254\" target=\"_blank\">JEP 254<\/a> definiert und ist per default aktiviert. Es kann mit <code>-XX:-CompactStrings<\/code> deaktiviert werden \u2013 dann werden Strings grunds\u00e4tzlich als UTF-16 gespeichert.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Was bedeutet das f\u00fcr unser Beispiel?<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Der String \"Hello world\" wird durch folgende Bytes repr\u00e4sentiert:<br> <pre>48 65 6c 6c 6f 20 77 6f 72 6c 64\n^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^\nH  e  l  l  o     W  o  r  l  d<\/pre><\/li>\n\n\n\n<li>Der String \"Hello world \u2713\" wird wie folgt gespeichert:<br> <pre style=\"margin-bottom: 0\">48 00 65 00 6c 00 6c 00 6f 00 20 00 77 00 6f 00 72 00 6c 00 64 00 20 00 13 27\n^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^ ^^^^^\n  H     e     l     l     o           W     o     r     l     d           \u2713<\/pre>(Hier im <a href=\"https:\/\/de.wikipedia.org\/wiki\/Byte-Reihenfolge#Little-Endian-Format\" target=\"_blank\" rel=\"noopener\">Little-Endian-Format<\/a>, da ich auf einem Intel-System arbeite.)<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Die Information, wie der String kodiert wird, wird im Feld <code>coder<\/code> des Strings abgelegt. Dabei steht eine 0 f\u00fcr Latin-1 und eine 1 f\u00fcr UTF-16.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Im String \"Hello world \u2713\" enth\u00e4lt das Feld <code>coder<\/code> also aufgrund der UTF-16-Kodierung den Wert 1.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Im vorangegangenen Code-Beispiel setzen wir das Feld <code>value<\/code> des Strings \"Hello world \u2713\" auf <code>\"You have been hacked\".getBytes()<\/code>. Die Methode <code>getBytes()<\/code> liefert die Bytes in der Standard-Zeichenkodierung zur\u00fcck, die \u2013 sofern nicht \u00fcber die System Property \"file.encoding\" anders definiert \u2013 UTF-8 ist (zumindest seit Java 1.5; davor war es ISO-8859-1).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Da der String \"You have been hacked\" keinerlei Sonderzeichen enth\u00e4lt, ist dessen UTF-8-Kodierung identisch mit seiner Latin-1-Kodierung, belegt also genau ein Byte pro Zeichen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Der String \"Hello world \u2713\" enth\u00e4lt somit im Feld <code>value<\/code> folgende Byte-Folge:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">59 6f 75 20 68 61 76 65 20 62 65 65 6e 20 68 61 63 6b 65 64\n^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^\nY  o  u     h  a  v  e     b  e  e  n     h  a  c  k  e  d<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Da im \"Hello world \u2713\"-Feld <code>coder<\/code> nach wie vor eine 1 steht (wegen der urspr\u00fcnglichen UTF-16-Kodierung), wird das Byte-Array als UTF-16 interpretiert \u2013 und genau das f\u00fchrt dann zur Ausgabe der chinesischen Zeichen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Grob gesagt haben wir also folgendes getan:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">byte<\/span>&#091;] bytes = <span class=\"hljs-string\">\"You have been hacked\"<\/span>.getBytes(StandardCharsets.UTF_8);\nString string = <span class=\"hljs-keyword\">new<\/span> String(bytes, StandardCharsets.UTF_16);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h4 class=\"wp-block-heading\">Wie k\u00f6nnen wir das Problem l\u00f6sen?<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Ziemlich einfach: wir m\u00fcssen lediglich neben dem Inhalt von <code>value<\/code> auch den Inhalt von <code>coder<\/code> kopieren. Bei der Gelegenheit \u00e4ndern wir auch das Kopieren von <code>value<\/code> so ab, dass wir das entsprechende Feld aus dem String \"You have been hacked\" auslesen, anstatt dessen <code>getBytes()<\/code>-Methode aufzurufen. Diese hat n\u00e4mlich bisher nur zuf\u00e4llig das zugrunde liegende Byte-Array geliefert, weil \"You have been hacked\" keine Sonderzeichen enth\u00e4lt und die System Property \"file.encoding\" (zumindest bei mir und h\u00f6chstwahrscheinlich auch bei dir) nicht gesetzt ist.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">ImpossibleThings8<\/span> <\/span>{\n  <span class=\"hljs-keyword\">static<\/span> {\n    <span class=\"hljs-keyword\">try<\/span> {\n      Field VALUE = String<span class=\"hljs-class\">.<span class=\"hljs-keyword\">class<\/span>.<span class=\"hljs-title\">getDeclaredField<\/span>(\"<span class=\"hljs-title\">value<\/span>\")<\/span>;\n      VALUE.setAccessible(<span class=\"hljs-keyword\">true<\/span>);\n\n      Field CODER = String<span class=\"hljs-class\">.<span class=\"hljs-keyword\">class<\/span>.<span class=\"hljs-title\">getDeclaredField<\/span>(\"<span class=\"hljs-title\">coder<\/span>\")<\/span>;\n      CODER.setAccessible(<span class=\"hljs-keyword\">true<\/span>);\n\n      VALUE.set(<span class=\"hljs-string\">\"Hello world \u2713\"<\/span>, VALUE.get(<span class=\"hljs-string\">\"You have been hacked\"<\/span>));\n      CODER.set(<span class=\"hljs-string\">\"Hello world \u2713\"<\/span>, CODER.get(<span class=\"hljs-string\">\"You have been hacked\"<\/span>));\n    } <span class=\"hljs-keyword\">catch<\/span> (ReflectiveOperationException e) {\n      <span class=\"hljs-keyword\">throw<\/span> <span class=\"hljs-keyword\">new<\/span> Error(e);\n    }\n  }\n\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">main<\/span><span class=\"hljs-params\">(String&#091;] args)<\/span> <\/span>{\n    System.out.println(<span class=\"hljs-string\">\"Hello world \u2713\"<\/span>);\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Statt chinesischer Zeichen bekommen wir nun wieder \"You have been hacked\" ausgegeben:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full_800\"><img decoding=\"async\" width=\"800\" height=\"176\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_chinese_fixed-800x176.png\" alt=\"Screenshot mit der Ausgabe von &quot;You have been hacked&quot; anstatt chinesischer Zeichen\" class=\"wp-image-10377\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_chinese_fixed-800x176.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_chinese_fixed-224x49.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_chinese_fixed-336x74.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_chinese_fixed-504x111.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_chinese_fixed-672x148.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_chinese_fixed-400x88.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_chinese_fixed-600x132.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_chinese_fixed.png 891w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><figcaption class=\"wp-element-caption\">Screenshot mit der Ausgabe von \"You have been hacked\" anstatt chinesischer Zeichen<\/figcaption><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">Dass die String-Konstanten hier zweimal angegeben werden, geh\u00f6rt sich so nat\u00fcrlich nicht. Das l\u00f6sen wir, in dem wir den Code in eine Methode auslagern und die zwei Strings als Parameter \u00fcbergeben: <\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">StringHacker_Java9<\/span> <\/span>{\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">hackString<\/span><span class=\"hljs-params\">(String victim, String replacement)<\/span> <\/span>{\n    <span class=\"hljs-keyword\">try<\/span> {\n      Field VALUE = String<span class=\"hljs-class\">.<span class=\"hljs-keyword\">class<\/span>.<span class=\"hljs-title\">getDeclaredField<\/span>(\"<span class=\"hljs-title\">value<\/span>\")<\/span>;\n      VALUE.setAccessible(<span class=\"hljs-keyword\">true<\/span>);\n\n      Field CODER = String<span class=\"hljs-class\">.<span class=\"hljs-keyword\">class<\/span>.<span class=\"hljs-title\">getDeclaredField<\/span>(\"<span class=\"hljs-title\">coder<\/span>\")<\/span>;\n      CODER.setAccessible(<span class=\"hljs-keyword\">true<\/span>);\n\n      VALUE.set(victim, VALUE.get(replacement));\n      CODER.set(victim, CODER.get(replacement));\n    } <span class=\"hljs-keyword\">catch<\/span> (ReflectiveOperationException e) {\n      <span class=\"hljs-keyword\">throw<\/span> <span class=\"hljs-keyword\">new<\/span> Error(e);\n    }\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Als n\u00e4chstes m\u00fcssen wir noch einen Blick auf \u00e4ltere Java-Versionen werfen.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"string-repraesentation-byte-vs-char\">String-Repr\u00e4sentation: byte[] vs. char[]<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Wie in der Einleitung dieses Kapitels erw\u00e4hnt, funktionieren die Beispiele nur mit  Java 9. Der Grund daf\u00fcr ist, dass bis zu Java 8 der Wert eines Strings nicht in einem <code>byte[]<\/code>, sondern in einem <code>char[]<\/code> abgelegt wurde. Entsprechend existierte auch bis Java 8 das Feld <code>coder<\/code> nicht.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">W\u00fcrden wir die bisherigen Beispiele mit Java 8 starten, bek\u00e4men wir ...<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>beim Aufruf von <code>VALUE.set(\"...\".getBytes())<\/code> eine <code>IllegalArgumentException: Can not set final [C field java.lang.String.value to [B<\/code><\/li>\n\n\n\n<li>in den letzten zwei Beispielen (in denen wir nicht explizit ein Byte-Array setzen, sondern den Inhalt von <code>value<\/code> kopieren) beim darauf folgenden Aufruf von <code>String.class.getDeclaredField(\"coder\")<\/code> eine <code>NoSuchFieldException: coder<\/code>.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Die <code>IllegalArgumentException<\/code> haben wir, wie gesagt, in den letzten zwei Beispielen schon verhindert. Die <code>NoSuchFieldException<\/code> k\u00f6nnen wir einfach ignorieren \u2013 wenn es das Feld <code>coder<\/code> nicht gibt, brauchen wir es auch nicht zu kopieren:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-14\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">StringHacker_Java7<\/span> <\/span>{\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">hackString<\/span><span class=\"hljs-params\">(String from, String to)<\/span> <\/span>{\n    <span class=\"hljs-keyword\">try<\/span> {\n      Field VALUE = String<span class=\"hljs-class\">.<span class=\"hljs-keyword\">class<\/span>.<span class=\"hljs-title\">getDeclaredField<\/span>(\"<span class=\"hljs-title\">value<\/span>\")<\/span>;\n      VALUE.setAccessible(<span class=\"hljs-keyword\">true<\/span>);\n      VALUE.set(from, VALUE.get(to));\n\n      <span class=\"hljs-comment\">\/\/ For \"Compact Strings\" introduced in Java 9<\/span>\n      <span class=\"hljs-keyword\">try<\/span> {\n        Field CODER = String<span class=\"hljs-class\">.<span class=\"hljs-keyword\">class<\/span>.<span class=\"hljs-title\">getDeclaredField<\/span>(\"<span class=\"hljs-title\">coder<\/span>\")<\/span>;\n        CODER.setAccessible(<span class=\"hljs-keyword\">true<\/span>);\n        CODER.set(from, CODER.get(to));\n      } <span class=\"hljs-keyword\">catch<\/span> (NoSuchFieldException e) {\n        <span class=\"hljs-comment\">\/\/ Ignore<\/span>\n      }\n    } <span class=\"hljs-keyword\">catch<\/span> (ReflectiveOperationException e) {\n      <span class=\"hljs-keyword\">throw<\/span> <span class=\"hljs-keyword\">new<\/span> Error(e);\n    }\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Hier der Beweis, dass dieser Code auch unter Java 7 l\u00e4uft:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full_800\"><img decoding=\"async\" width=\"800\" height=\"96\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_java7_v2-800x96.png\" alt=\"String Deep Reflection mit Java 7\" class=\"wp-image-10587\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_java7_v2-800x96.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_java7_v2-224x27.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_java7_v2-336x40.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_java7_v2-504x61.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_java7_v2-672x81.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_java7_v2-400x48.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_java7_v2-600x72.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_java7_v2.png 891w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><figcaption class=\"wp-element-caption\">String Deep Reflection mit Java 7<\/figcaption><\/figure>\n<\/div>\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"sub-strings-mit-offset-und-count\">Sub-Strings mit offset und count<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Gehen wir weiter in der Java-Geschichte zur\u00fcck, kommen wir zu einer weiteren \u00c4nderung der String-Interna von Java 6 zu Java 7. Bis Java 6 wurde das <code>value<\/code>-Character-Array wiederverwendet, wenn man mit <code><a href=\"\/de\/java\/substring-methode\/\">String.substring()<\/a><\/code> einen Teil-String erzeugt hat. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Dazu wurde das Character-Array des urspr\u00fcnglichen Strings in den Teil-String unver\u00e4ndert \u00fcbernommen. Und in den Feldern <code>offset<\/code> und <code>count<\/code> des Teil-Strings wurde gespeichert, welcher Abschnitt des Character-Arrays dessen Inhalt repr\u00e4sentiert.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ziel dieser Logik war es Speicher zu sparen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">H\u00e4ufiger passierte jedoch das Gegenteil: Wenn der urspr\u00fcngliche String nicht mehr ben\u00f6tigt wurde, hielt der k\u00fcrzere Teil-String nach wie vor eine Referenz auf das urspr\u00fcngliche, dann unn\u00f6tig l\u00e4ngere Character-Array. Von daher haben die Java-Entwickler in Java 7 die Funktionalit\u00e4t von <code>String.substring()<\/code> so ge\u00e4ndert, dass nur der ben\u00f6tigte Teil des Character-Arrays in den Teil-String kopiert wurde.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Um unseren Code auf Java 6 und niedriger lauff\u00e4hig zu machen, m\u00fcssen wir also auch die Felder <code>offset<\/code> und <code>count<\/code> kopieren.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Vor Java 7 gab es leider auch weder die <code>ReflectiveOperationException<\/code>, noch die M\u00f6glichkeit mehrere Exception-Typen in einem <code>catch<\/code>-Block abzufangen, so dass dieser etwas umst\u00e4ndlicher wird. Hier der auch unter 6 lauff\u00e4hige Code:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-15\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">StringHacker<\/span> <\/span>{\n  <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">hackString<\/span><span class=\"hljs-params\">(String from, String to)<\/span> <\/span>{\n    <span class=\"hljs-keyword\">try<\/span> {\n      Field VALUE = String<span class=\"hljs-class\">.<span class=\"hljs-keyword\">class<\/span>.<span class=\"hljs-title\">getDeclaredField<\/span>(\"<span class=\"hljs-title\">value<\/span>\")<\/span>;\n      VALUE.setAccessible(<span class=\"hljs-keyword\">true<\/span>);\n      VALUE.set(from, VALUE.get(to));\n\n      <span class=\"hljs-comment\">\/\/ \"offset\" and \"count\" for Strings up to Java 6<\/span>\n      <span class=\"hljs-keyword\">try<\/span> {\n        Field OFFSET = String<span class=\"hljs-class\">.<span class=\"hljs-keyword\">class<\/span>.<span class=\"hljs-title\">getDeclaredField<\/span>(\"<span class=\"hljs-title\">offset<\/span>\")<\/span>;\n        OFFSET.setAccessible(<span class=\"hljs-keyword\">true<\/span>);\n        OFFSET.setInt(from, OFFSET.getInt(to));\n\n        Field COUNT = String<span class=\"hljs-class\">.<span class=\"hljs-keyword\">class<\/span>.<span class=\"hljs-title\">getDeclaredField<\/span>(\"<span class=\"hljs-title\">count<\/span>\")<\/span>;\n        COUNT.setAccessible(<span class=\"hljs-keyword\">true<\/span>);\n        COUNT.setInt(from, COUNT.getInt(to));\n      } <span class=\"hljs-keyword\">catch<\/span> (NoSuchFieldException e) {\n        <span class=\"hljs-comment\">\/\/ Ignore<\/span>\n      }\n\n      <span class=\"hljs-comment\">\/\/ For \"Compact Strings\" introduced in Java 9<\/span>\n      <span class=\"hljs-keyword\">try<\/span> {\n        Field CODER = String<span class=\"hljs-class\">.<span class=\"hljs-keyword\">class<\/span>.<span class=\"hljs-title\">getDeclaredField<\/span>(\"<span class=\"hljs-title\">coder<\/span>\")<\/span>;\n        CODER.setAccessible(<span class=\"hljs-keyword\">true<\/span>);\n        CODER.set(from, CODER.get(to));\n      } <span class=\"hljs-keyword\">catch<\/span> (NoSuchFieldException e) {\n        <span class=\"hljs-comment\">\/\/ Ignore<\/span>\n      }\n    } <span class=\"hljs-keyword\">catch<\/span> (IllegalAccessException e) {\n      e.printStackTrace();\n    } <span class=\"hljs-keyword\">catch<\/span> (NoSuchFieldException e) {\n      e.printStackTrace();\n    }\n  }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-15\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Der folgende Screenshot zeigt, wie der Code unter Java 6 l\u00e4uft:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full_800\"><img decoding=\"async\" width=\"800\" height=\"95\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_java6_v2-800x95.png\" alt=\"String Deep Reflection mit Java 6\" class=\"wp-image-10585\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_java6_v2-800x95.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_java6_v2-224x27.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_java6_v2-336x40.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_java6_v2-504x60.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_java6_v2-672x80.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_java6_v2-400x48.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_java6_v2-600x71.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_java6_v2.png 892w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><figcaption class=\"wp-element-caption\">String Deep Reflection mit Java 6<\/figcaption><\/figure>\n<\/div>\n\n\n<h3 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"experiment-compressed-strings-in-java-6u21\">Experiment \"Compressed Strings\" in Java 6u21<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Der Artikel w\u00e4re nicht vollst\u00e4ndig, w\u00fcrden wir nicht kurz auf die in Java 6 als \"experimental\" eingef\u00fchrten \"Compressed Strings\" eingehen (nicht zu verwechseln mit den o. g. in Java 9 eingef\u00fchrten \"<em>Compact<\/em> Strings\"!).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Wenn \u00fcber die VM-Option <code>-XX:+UseCompressedStrings<\/code> aktiviert, dann wird, sofern ein String nur Latin-1-Zeichen enth\u00e4lt, im <code>value<\/code>-Feld anstatt eines Character-Arrays ein Byte-Array gespeichert. Dies wurde jedoch nicht im String-Quellcode gemacht, sondern intern in der JVM. Diese Optimierung hat zwar Speicher gespart, war aber sehr unperformant, da das Byte-Array f\u00fcr die fast alle String-Operationen in ein Character-Array konvertiert werden musste. In Java 7 wurde die Funktion wieder entfernt.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Da diese Optimierung JVM-intern durchgef\u00fchrt wurde, ist unser Code ohne weitere Anpassung auch mit aktivierten \"Compressed Strings\" lauff\u00e4hig:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full_800\"><img decoding=\"async\" width=\"800\" height=\"95\" src=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_java6_UseCompressedStrings-800x95.png\" alt=\"String Deep Reflection mit Java 6 und &quot;-XX:+UseCompressedStrings&quot;\" class=\"wp-image-10584\" srcset=\"https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_java6_UseCompressedStrings-800x95.png 800w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_java6_UseCompressedStrings-224x27.png 224w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_java6_UseCompressedStrings-336x40.png 336w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_java6_UseCompressedStrings-504x60.png 504w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_java6_UseCompressedStrings-672x80.png 672w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_java6_UseCompressedStrings-400x48.png 400w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_java6_UseCompressedStrings-600x71.png 600w, https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java_string_deep_reflection_magic_java6_UseCompressedStrings.png 892w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><figcaption class=\"wp-element-caption\">String Deep Reflection mit Java 6 und \"-XX:+UseCompressedStrings\"<\/figcaption><\/figure>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\" class=\"wp-block-heading\" id=\"fazit\">Fazit<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In der Praxis solltet ihr davon absehen, die internen Werte von gecachten Integer-Objekten oder von Strings zu ver\u00e4ndern. Dies k\u00f6nnte unvorhersehbare Konsequenzen haben. Die \u00c4nderung hat nicht nur Auswirkungen auf euren eigenen Code, sondern auch auf den restlichen Code des Projekts inklusive aller Libraries und Frameworks, die vom selben Classloader geladen werden.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ihr solltet euch auch nicht auf die interne Repr\u00e4sentation einer Klasse verlassen. Wie am String-Beispiel gezeigt, kann sich diese von einer Java-Version zur n\u00e4chsten \u00e4ndern.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Au\u00dferdem bekommen wir f\u00fcr die Code-Beispiele aus diesem Artikel seit Java 9 eine Fehlermeldung:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><em>An illegal reflective access operation has occurred <\/em><br><em>[...] <\/em><br><em>All illegal access operations will be denied in a future release<\/em><\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Das bedeutet: Wir d\u00fcrfen nicht davon ausgehen, dass unser Code f\u00fcr immer und ewig funktioniert. In Java 14 (release candidate) und 15 (early access) allerdings funktioniert der Code nach wie vor. Und da zahlreiche 3rd-Party-Frameworks von Deep Reflection Gebrauch machen, wird Oracle diese Funktion auch sicher in absehbarer nicht Zukunft entfernen.<\/p>\n<aside><p>Wenn dir der Artikel weitergeholfen hat, w\u00fcrde ich mich sehr \u00fcber eine positive Bewertung auf meinem <a href=\"https:\/\/www.provenexpert.com\/de-de\/sven-woltmann-happycoders-eu\/7smk\/\" target=\"_blank\" rel=\"noopener\">ProvenExpert-Profil<\/a> freuen. Dein Feedback hilft mir, meine Inhalte weiter zu verbessern und motiviert mich, neue informative Artikel zu schreiben.<\/p>\r\n                        <p>\ud83d\udc49 <a href=\"https:\/\/www.provenexpert.com\/de-de\/sven-woltmann-happycoders-eu\/7smk\/\" target=\"_blank\" rel=\"noopener\">Bewertung abgeben<\/a><\/p>\r\n                        <p>Du m\u00f6chtest \u00fcber alle neuen Java-Features auf dem Laufenden sein? Dann <a href=\"#\" data-formkit-toggle=\"d8ee997126\">klicke hier<\/a>, um dich f\u00fcr den HappyCoders-Newsletter anzumelden.<\/p>\r\n                        <p>\ud83d\udc49 <a href=\"#\" data-formkit-toggle=\"d8ee997126\">Newsletter-Anmeldung<\/a><\/p><\/aside>","protected":false},"excerpt":{"rendered":"<p>In diesem Artikel zeige ich dir, wie du Deep Reflection verwenden kannst, um die Werte von Integer- und String-Objekten zur Laufzeit zu \u00e4ndern.<\/p>\n","protected":false},"author":1,"featured_media":34477,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_seopress_titles_title":"","_seopress_titles_desc":"Kann in Java 2+3 = 6 sein? Lerne, wie man mit Deep Reflection zur Laufzeit die Werte von Integern und Strings ver\u00e4ndern kann!","_seopress_robots_index":"","_seopress_robots_follow":"","_seopress_robots_imageindex":"","_seopress_robots_snippet":"","_seopress_robots_primary_cat":"none","_seopress_robots_breadcrumbs":"","_seopress_robots_freeze_modified_date":"","_seopress_robots_custom_modified_date":"","_seopress_robots_canonical":"","_seopress_social_fb_title":"","_seopress_social_fb_desc":"","_seopress_social_fb_img":"","_seopress_social_fb_img_attachment_id":0,"_seopress_social_fb_img_width":0,"_seopress_social_fb_img_height":0,"_seopress_social_twitter_title":"","_seopress_social_twitter_desc":"","_seopress_social_twitter_img":"","_seopress_social_twitter_img_attachment_id":0,"_seopress_social_twitter_img_width":0,"_seopress_social_twitter_img_height":0,"_seopress_redirections_value":"","_seopress_redirections_enabled":"","_seopress_redirections_enabled_regex":"","_seopress_redirections_logged_status":"both","_seopress_redirections_param":"","_seopress_redirections_type":301,"_seopress_analysis_target_kw":"deep reflection","_seopress_news_disabled":"","_seopress_video_disabled":"","_seopress_video":[{"url":"","title":"","desc":"","thumbnail":"","duration":"","rating":"","view_count":"","tag":"","cat":""}],"_seopress_pro_schemas_manual":[{"_seopress_pro_rich_snippets_type":"none"}],"_seopress_pro_rich_snippets_disable_all":"","_seopress_pro_rich_snippets_disable":[],"_seopress_pro_schemas":[],"_uag_custom_page_level_css":"","_wp_convertkit_post_meta":{"form":"-1","landing_page":"","tag":"0","restrict_content":"0"},"_metis_text_type":"standard","_metis_text_length":19887,"_post_count":0,"footnotes":""},"categories":[64],"tags":[165],"class_list":["post-9557","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-java","tag-java-fortgeschritten"],"uagb_featured_image_src":{"full":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java-deep-reflection.jpg",1770,986,false],"thumbnail":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java-deep-reflection.jpg",150,84,false],"medium":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java-deep-reflection.jpg",300,167,false],"medium_large":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java-deep-reflection.jpg",768,428,false],"large":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java-deep-reflection.jpg",1024,570,false],"feature_thumb_224":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java-deep-reflection-224x125.jpg",224,125,true],"feature_thumb_336":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java-deep-reflection-336x187.jpg",336,187,true],"feature_thumb_504":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java-deep-reflection-504x281.jpg",504,281,true],"feature_thumb_672":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java-deep-reflection-672x374.jpg",672,374,true],"half_400":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java-deep-reflection-400x223.jpg",400,223,true],"half_600":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java-deep-reflection-600x334.jpg",600,334,true],"full_800":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java-deep-reflection-800x446.jpg",800,446,true],"full_944":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java-deep-reflection-944x526.jpg",944,526,true],"full_1200":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java-deep-reflection-1200x668.jpg",1200,668,true],"wide_1180":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java-deep-reflection-1180x490.jpg",1180,490,true],"wide_1770":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java-deep-reflection-1770x735.jpg",1770,735,true],"1536x1536":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java-deep-reflection.jpg",1536,856,false],"2048x2048":["https:\/\/www.happycoders.eu\/wp-content\/uploads\/2020\/03\/java-deep-reflection.jpg",1770,986,false]},"uagb_author_info":{"display_name":"Sven Woltmann","author_link":"https:\/\/www.happycoders.eu\/de\/author\/sven\/"},"uagb_comment_info":0,"uagb_excerpt":"In diesem Artikel zeige ich dir, wie du Deep Reflection verwenden kannst, um die Werte von Integer- und String-Objekten zur Laufzeit zu \u00e4ndern.","public_identification_id":"3ffdb6f190fe4b73a3ad8453db9348a7","private_identification_id":"4007ca6a61104cb2bc522794e9235c3a","_links":{"self":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/9557","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/comments?post=9557"}],"version-history":[{"count":10,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/9557\/revisions"}],"predecessor-version":[{"id":52427,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/posts\/9557\/revisions\/52427"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/media\/34477"}],"wp:attachment":[{"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/media?parent=9557"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/categories?post=9557"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.happycoders.eu\/de\/wp-json\/wp\/v2\/tags?post=9557"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}