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

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

如何修改int的打印內(nèi)容——從一道面試題說(shuō)起

2019-11-11 00:05:57
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

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

解題思路

解題的思路無(wú)外乎是3種方法: 1.作弊大法,因?yàn)橐恍┟嬖囶}總是會(huì)出其不意,面對(duì)扯淡的問(wèn)題就要用扯淡的方法。 2.反射,感覺(jué)反射是一種比較“高端”用法,因?yàn)楹芏嘀虚g件與框架都是通過(guò)反射實(shí)現(xiàn)的。 3.數(shù)據(jù)流。反射的思路是修改對(duì)應(yīng)內(nèi)存上的內(nèi)容,當(dāng)無(wú)法修改響應(yīng)內(nèi)存的時(shí)候就要找其他思路了。這里對(duì)應(yīng)的問(wèn)題就是,System.out.println是如何打印的。

解題方案

作弊大法

System.exit 這種方法通過(guò)退出jvm線程來(lái)終止后面的程序運(yùn)行,看完之后讓人比較崩潰,因?yàn)闃I(yè)務(wù)中遇到 System.exit的場(chǎng)景比較少。 private static void method(int a, int b) { System.out.println("a=100"); System.out.println("b=200"); System.exit(0); }異常 上面的方法是線程優(yōu)雅的自己退出JVM,通過(guò)異常就是強(qiáng)制使JVM中介當(dāng)前線程了。 private static void method(int a, int b) { System.out.println("a=100"); System.out.println("b=200"); throw new RuntimeException(); }

反射

反射的方法我一直沒(méi)有成功,這里提供幾個(gè)思路

修改緩存池 因?yàn)镮nteger內(nèi)部維護(hù)了一個(gè)IntegerCache內(nèi)部類,其內(nèi)部維護(hù)了一個(gè)Integer[]數(shù)組來(lái)維護(hù)從-128到127的Integer對(duì)象。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;}

這樣就修改了緩存區(qū)的內(nèi)容,但是依然沒(méi)有完成題目的要求,打印內(nèi)容沒(méi)有改變,因?yàn)檫@樣改變了所有的Integer緩存區(qū)對(duì)象,但是當(dāng)前打印的是int。這種情況下,其他的場(chǎng)景倒是可以改變了。

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

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

修改輸出流

了解一點(diǎn)System.out的同學(xué)應(yīng)該很清楚這是通過(guò)PringStream流實(shí)現(xiàn)的。當(dāng)然我不是很了解,我是通過(guò)反編譯看字節(jié)碼發(fā)現(xiàn)的。 測(cè)試代碼:

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

查看字節(jié)碼: 這里寫(xiě)圖片描述 發(fā)現(xiàn)實(shí)際在輸出屏幕的時(shí)候調(diào)用的是PrintStream對(duì)象的println方法實(shí)現(xiàn)的,我們可以通過(guò)重寫(xiě)這個(gè)方法打印任何內(nèi)容。

直接替換法 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,屬于手動(dòng)替換的。下面的方法性質(zhì)相同,不過(guò)看上去高端一點(diǎn)。

間接替換法 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);}

結(jié)論

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


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 锡林浩特市| 洛阳市| 鄂伦春自治旗| 启东市| 汝阳县| 泗洪县| 青阳县| 威信县| 阿拉善左旗| 黎川县| 蓬莱市| 栾城县| 耿马| 合山市| 邳州市| 莒南县| 汉沽区| 裕民县| 兴国县| 潼关县| 静海县| 和静县| 右玉县| 陆河县| 色达县| 油尖旺区| 应用必备| 五莲县| 临澧县| 望谟县| 宝清县| 武清区| 华蓥市| 公安县| 稷山县| 景德镇市| 罗田县| 邻水| 宜阳县| 景德镇市| 绍兴县|