国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

如何修改int的打印內容——從一道面試題說起

2019-11-11 01:34:56
字體:
來源:轉載
供稿:網友

今天看到了一個比較特別的面試題,考察的是如何改變int的System.out.PRint的結果。題目如下: 這里寫圖片描述 下面的一句話“這是初級java實習生面試題”非常挑釁的激起了大家做題的欲望。

解題思路

解題的思路無外乎是3種方法: 1.作弊大法,因為一些面試題總是會出其不意,面對扯淡的問題就要用扯淡的方法。 2.反射,感覺反射是一種比較“高端”用法,因為很多中間件與框架都是通過反射實現的。 3.數據流。反射的思路是修改對應內存上的內容,當無法修改響應內存的時候就要找其他思路了。這里對應的問題就是,System.out.println是如何打印的。

解題方案

作弊大法

System.exit 這種方法通過退出jvm線程來終止后面的程序運行,看完之后讓人比較崩潰,因為業務中遇到 System.exit的場景比較少。 private static void method(int a, int b) { System.out.println("a=100"); System.out.println("b=200"); System.exit(0); }異常 上面的方法是線程優雅的自己退出JVM,通過異常就是強制使JVM中介當前線程了。 private static void method(int a, int b) { System.out.println("a=100"); System.out.println("b=200"); throw new RuntimeException(); }

反射

反射的方法我一直沒有成功,這里提供幾個思路

修改緩存池 因為Integer內部維護了一個IntegerCache內部類,其內部維護了一個Integer[]數組來維護從-128到127的Integer對象。private static void method(int a, int b) throws Exception { Class<?> clzz = Integer.class.getDeclaredClasses()[0]; Field field = clzz.getDeclaredField("cache"); field.setaccessible(true); Integer[] cache = (Integer[]) field.get(clzz); cache[138]=100; cache[148]=200;}

這樣就修改了緩存區的內容,但是依然沒有完成題目的要求,打印內容沒有改變,因為這樣改變了所有的Integer緩存區對象,但是當前打印的是int。這種情況下,其他的場景倒是可以改變了。

Integer c =10;System.out.println(c);System.out.println(Integer.valueOf(10));修改對象本身private static void method(int a, int b) throws Exception { Field value = Integer.class.getDeclaredField("value"); value.setAccessible(true); value.set(10,100);}

效果等于同修改緩存池的方法

修改輸出流

了解一點System.out的同學應該很清楚這是通過PringStream流實現的。當然我不是很了解,我是通過反編譯看字節碼發現的。 測試代碼:

public class A { public static void main(String[] args) { int a = 9; System.out.println(a); }}

查看字節碼: 這里寫圖片描述 發現實際在輸出屏幕的時候調用的是PrintStream對象的println方法實現的,我們可以通過重寫這個方法打印任何內容。

直接替換法 private static void method(int a, int b) throws Exception { PrintStream printStream = new PrintStream(System.out) { @Override public void print(String s) { if (s.equals("a=10")) { super.print("a=100"); } else if (s.equals("b=20")) { super.print("b=200"); } else super.print(s); } }; System.setOut(printStream);}

這種方法比較low,屬于手動替換的。下面的方法性質相同,不過看上去高端一點。

間接替換法 private static void method(int a, int b) throws Exception { PrintStream printStream = new PrintStream(System.out) { @Override public void print(String s) { s = s.replace(a + "", a * 10 + "").replace(b + "", b * 10 + ""); super.print(s); } }; System.setOut(printStream);}

結論

不知道這個面試題的正確答案是什么,這里提供了兩種方法解決。很可惜反射沒有搞定這個題目,如果哪位同學有更好的方法請留言。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 永寿县| 永胜县| 遵化市| 鄂尔多斯市| 克拉玛依市| 浙江省| 华蓥市| 汉沽区| 林西县| 杨浦区| 延吉市| 镇远县| 建昌县| 合阳县| 福建省| 阿克陶县| 富蕴县| 永川市| 会泽县| 伊吾县| 上虞市| 兰坪| 三门峡市| 孟村| 磐石市| 育儿| 关岭| 天峻县| 两当县| 安多县| 阳春市| 通许县| 海安县| 柳林县| 定日县| 大埔县| 庆阳市| 宝坻区| 峨眉山市| 中卫市| 常宁市|