国产探花免费观看_亚洲丰满少妇自慰呻吟_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);}

結論

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


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 芦山县| 夏河县| 庄河市| 姚安县| 竹山县| 赞皇县| 疏附县| 辽阳县| 阳朔县| 临洮县| 长阳| 莆田市| 贵溪市| 怀集县| 荔浦县| 霍山县| 嘉兴市| 开封市| 报价| 郑州市| 银川市| 黔西县| 手游| 普兰店市| 丘北县| 佛学| 松滋市| 亚东县| 甘泉县| 盐池县| 黄龙县| 敦煌市| 万全县| 怀柔区| 剑川县| 铜山县| 桂东县| 静海县| 迁安市| 沽源县| 宜阳县|