リフレクションは黒魔術っぽいなぁと思うわけです.
Field value = String.class.getDeclaredField("value"); Field count = String.class.getDeclaredField("count"); value.setAccessible(true); count.setAccessible(true); value.set("hoge", "bar".toCharArray()); count.set("hoge", "bar".length()); System.out.println("hoge"); System.out.println("hoge".equals("bar"));
これの結果が
bar true
になったりします.
(あ,コンパイラによっては違うかも……)
折角なので String を可変オブジェクトっぽく使えるクラスを作ってみますた.
スレッドセーフとか考えてないです.
Map の Key とかに使うと面白いと思います.
import java.lang.reflect.Field; public class MutableStrings { private static Field value; private static Field count; static { try { value = String.class.getDeclaredField("value"); count = String.class.getDeclaredField("count"); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } value.setAccessible(true); count.setAccessible(true); } public static String concat(String target, String str) { return change(target,target.concat(str)); } public static String replaceAll(String target, String regex, String replacement) { return change(target,target.replaceAll(regex, replacement)); } public static String substring(String target, int beginIndex) { return change(target,target.substring(beginIndex)); } public static String substring(String target, int beginIndex, int endIndex) { return change(target,target.substring(beginIndex, endIndex)); } public static String change(String target,String newString) { char[] newChars = newString.toCharArray(); try { value.set(target, newChars); count.set(target, newChars.length); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } return target; } }
id:daisuke-m
http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/java/util/Map.html
注: 可変オブジェクトをマップキーとして使用する場合は細心の注意が必要です。オブジェクトがマップ内のキーであるときに、equals の比較に影響を与える方法でオブジェクトの値が変更された場合、マップの動作は保証されません。らしい。前、id:ashigeruに教わった〜
http://d.hatena.ne.jp/Yoshiori/20090522/1242977770#c1242978353
可変オブジェクトの定義って何ですかね?:)