jvm 宕机 打印jvm_通过入侵JVM打印阵列
jvm 宕機(jī) 打印jvm
總覽
Java中最常見的陷阱之一就是知道如何打印數(shù)組。 如果有關(guān)如何打印陣列的答案獲得了超過1000票贊成票,那么您必須懷疑是否有更簡單的方法。 幾乎所有其他流行語言都具有這種更簡單的方法,所以我不清楚為什么Java仍會(huì)這樣做。
與其他JDK類不同,數(shù)組沒有特別健全的toString(),因?yàn)樗菑腛bject繼承的。
它打印類型和地址嗎?
實(shí)際上,它不打印地址,只是看起來像一個(gè)地址一樣。 它打印類型的內(nèi)部表示形式以及對(duì)象的hashCode() 。 由于所有數(shù)組都是對(duì)象,因此它們具有hashCode()和類型以及同步鎖,而對(duì)象具有的其他所有內(nèi)容,但是沒有特定于數(shù)組的方法。 這就是為什么toString()對(duì)數(shù)組沒有用的原因。
看起來沒有什么變化?
如果我運(yùn)行以下程序。
public class ObjectTest {boolean[] booleans = {true, false};byte[] bytes = {1, 2, 3};char[] chars = "Hello World".toCharArray();short[] shorts = {111, 222, 333};float[] floats = {1.0f, 2.2f, 3.33f, 44.44f, 55.555f, 666.666f};int[] ints = {1, 22, 333, 4_444, 55_555, 666_666};double[] doubles = {Math.PI, Math.E};long[] longs = {System.currentTimeMillis(), System.nanoTime()};String[] words = "The quick brown fox jumps over the lazy dog".split(" ");@Testpublic void testToString() throws IllegalAccessException {Map<String, Object> arrays = new LinkedHashMap<>();for(Field f : getClass().getDeclaredFields())arrays.put(f.getName(), f.get(this));arrays.entrySet().forEach(System.out::println);} }它打印。
booleans=[Z@277c0f21 bytes=[B@6073f712 chars=[C@43556938 shorts=[S@3d04a311 floats=[F@7a46a697 ints=[I@5f205aa doubles=[D@6d86b085 longs=[J@75828a0f words=[Ljava.lang.String;@3abfe836我認(rèn)為這對(duì)每個(gè)人都是顯而易見的。 O_O喜歡的事實(shí),J是一個(gè)升翁內(nèi)部碼和L為的J ava類的內(nèi)部碼。 當(dāng)b未使用時(shí), Z也是布爾值的代碼。
我們對(duì)于它可以做些什么呢?
在此程序中,我們最終不得不編寫一個(gè)特殊的toString方法,以供需要通過打印Map.Entry的特殊方法調(diào)用對(duì)象時(shí)使用。 重復(fù)此操作多次可以提高程序的吞吐量,并且避免在Java中使用數(shù)組很容易,因?yàn)樗鼈兒茈y調(diào)試。
黑客JVM呢?
我們可以做的就是更改Object.toString()。 我們必須更改此類,因?yàn)樗俏覀冇袡?quán)訪問的數(shù)組的唯一父級(jí)。 我們無法更改數(shù)組的代碼,因?yàn)樗荍VM內(nèi)部的。 例如,對(duì)于所有byte []特定方法,沒有byte [] Java類文件。
取得java.lang.Object的源代碼副本,并將toString()替換為
public String toString() {if (this instanceof boolean[])return Arrays.toString((boolean[]) this);if (this instanceof byte[])return Arrays.toString((byte[]) this);if (this instanceof short[])return Arrays.toString((short[]) this);if (this instanceof char[])return Arrays.toString((char[]) this);if (this instanceof int[])return Arrays.toString((int[]) this);if (this instanceof long[])return Arrays.toString((long[]) this);if (this instanceof float[])return Arrays.toString((float[]) this);if (this instanceof double[])return Arrays.toString((double[]) this);if (this instanceof Object[])return Arrays.deepToString((Object[]) this);return getClass().getName() + "@" + Integer.toHexString(hashCode());}在Java <= 8中,我們可以通過添加到命令行將此類添加到bootclasspath的開頭
-Xbootclasspath/p:target/classes(或您的類已編譯到的任何位置),現(xiàn)在當(dāng)我們運(yùn)行程序時(shí),我們看到
booleans=[true, false] bytes=[1, 2, 3] chars=[H, e, l, l, o, , W, o, r, l, d] shorts=[111, 222, 333] floats=[1.0, 2.2, 3.33, 44.44, 55.555, 666.666] ints=[1, 22, 333, 4444, 55555, 666666] doubles=[3.141592653589793, 2.718281828459045] longs=[1457629893500, 1707696453284240] words=[The, quick, brown, fox, jumps, over, the, lazy, dog]就像您使用其他任何語言一樣。
結(jié)論
雖然這是一個(gè)很酷的技巧,但是最好的解決方案是他們最終修復(fù)Java,以便為數(shù)組生成合理的輸出。 它知道您需要一個(gè)并提供了它,但是將其隱藏在您必須通過Google查找的類中,以便每個(gè)新的Java開發(fā)人員在第一次嘗試使用數(shù)組時(shí)都必須擁有一個(gè)WTF時(shí)刻。
翻譯自: https://www.javacodegeeks.com/2016/03/printing-arrays-hacking-jvm.html
jvm 宕機(jī) 打印jvm
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的jvm 宕机 打印jvm_通过入侵JVM打印阵列的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: javaio流层次结构_流的多层次分组
- 下一篇: 动量的单位是什么 动量的单位是啥