1. 程式人生 > >Java命令之javap初探

Java命令之javap初探

javap是jdk自帶的一個工具在jdk安裝目錄的/bin下面可以找到,可以對程式碼反編譯,也可以檢視java編譯器生成的位元組碼,對程式碼的執行過程進行分析,瞭解jvm內部的工作。

下面列舉javap命令的常用options及其功能描述,更多功能的使用請自行Google,樓主不做贅述。

用法摘要

-help 幫助
-l 輸出行和變數的表
-public 只輸出public方法和域
-protected 只輸出public和protected類和成員
-package 只輸出包,public和protected類和成員,這是預設的
-p -private 輸出所有類和成員
-s 輸出內部型別簽名 -c 輸出分解後的程式碼,例如,類中每一個方法內,包含java位元組碼的指令, -verbose 輸出棧大小,方法引數的個數 -constants 輸出靜態final常量

例項分析

javap命令分解一個class檔案,它根據options來決定到底輸出什麼。如果沒有使用options,那麼javap將會輸出該class檔案中的包,類裡的protected和public域以及類裡的所有方法。javap將會把它們輸出在標準輸出上。來看這個例子,先編譯(javac)下面這個類。

package com.thundersoft.metadata.test.kafka
; import org.apache.kafka.clients.consumer.ConsumerRecord; import org.apache.kafka.clients.consumer.ConsumerRecords; import org.apache.kafka.clients.consumer.KafkaConsumer; import org.apache.kafka.clients.producer.KafkaProducer; import org.apache.kafka.clients.producer.Producer; import org.apache.kafka
.clients.producer.ProducerRecord; import org.junit.Test; import java.util.Arrays; import java.util.Properties; public class KafkaTest { @Test public void testProducer() { Properties props = new Properties(); props.put("bootstrap.servers", "192.168.204.30:9092"); props.put("acks", "all"); props.put("retries", 0); props.put("batch.size", 16384); props.put("linger.ms", 1); props.put("buffer.memory", 33554432); props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer"); props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer"); Producer<String, String> producer = new KafkaProducer<>(props); for(int i = 0; i < 100; i++) { producer.send(new ProducerRecord<String, String>("my-topic", Integer.toString(i), Integer.toString(i))); } producer.close(); } @Test public void testKafkaConsumer() { Properties props = new Properties(); props.put("bootstrap.servers", "192.168.204.30:9092"); props.put("group.id", "test"); props.put("enable.auto.commit", "true"); props.put("auto.commit.interval.ms", "1000"); props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer"); props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer"); KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props); consumer.subscribe(Arrays.asList("my-topic")); while (true) { ConsumerRecords<String, String> records = consumer.poll(100); for (ConsumerRecord<String, String> record : records) System.out.printf("offset = %s, key = %s, value = %s%n", record.topic(), record.key(), record.value()); } } public static void main(String[] args) { int a = 2; int b = 3; int sum = a*b; System.out.println(sum); } }

在命令列上鍵入javap KafkaTest後,輸出結果如下

public class com.thundersoft.metadata.test.kafka.KafkaTest {
  public com.thundersoft.metadata.test.kafka.KafkaTest();
  public void testProducer();
  public void testKafkaConsumer();
  public static void main(java.lang.String[]);
}

結合程式碼分析編譯器執行過程

這裡只關注main方法內部的程式碼邏輯,main方法程式碼如下

 public static void main(String[] args) {
        int a = 2;
        int b = 3;
        int sum = a*b;
        System.out.println(sum);
    }

在命令列上鍵入javap -c KafkaTest後,輸出結果如下

 public static void main(java.lang.String[]);
    Code:
       0: iconst_2
       1: istore_1
       2: iconst_3
       3: istore_2
       4: iload_1
       5: iload_2
       6: imul
       7: istore_3
       8: getstatic     #47                 // Field java/lang/System.out:Ljava/io/PrintStream;
      11: iload_3
      12: invokevirtual #54                 // Method java/io/PrintStream.println:(I)V
      15: return

如上面程式碼所,iconst_2 與iconst_3分別代表常量2,3 。istore_1 ,istore_2 分別代表定義兩個普通變數,iload_1 , iload_2 分別表示載入istore_1,istore_2 兩個變數到資料棧中,imul表示兩個變數做乘法運算,結果賦值給變數istore_3,最後將結果輸出,程式返回。

在分析這段簡單程式碼的過程中,樓主發現了一個jvm編譯命令的網站,分享出來jvm指令

總結

樓主在上面做了一個簡單的程式碼分析的過程,希望可以幫助到有緣人。javap可以用於反編譯和檢視編譯器編譯後的位元組碼。一般用到的不多,不過平時用javap -c比較多,該命令用於列出每個方法所執行的JVM指令,用來解決比較棘手的邏輯出錯的bug是個不錯的選擇。另外通過位元組碼和原始碼的對比,深入分析java的編譯原理及程式碼執行過程,解決各種Java原理級別的問題。

相關推薦

Java命令javap初探

javap是jdk自帶的一個工具在jdk安裝目錄的/bin下面可以找到,可以對程式碼反編譯,也可以檢視java編譯器生成的位元組碼,對程式碼的執行過程進行分析,瞭解jvm內部的工作。 下面列舉javap命令的常用options及其功能描述,更多功能的使

Java IOFileChannel初探

概述 對於檔案的複製,平時我們都是使用輸入輸出流進行操作,利用原始檔創建出一個輸入流,然後利用目標檔案創建出一個輸出流,最後將輸入流的資料讀取寫入到輸出流中。這樣也是可以進行操作的。但是利用fileChannel是很有用的一個方式。它能直接連線輸入輸出流的檔案通道,將資料直接寫入到目標檔案中去。

Java集合初探(一)

lin 數據改變 排序。 方法 規則 找不到 集合 回收 for循環 一、集合概述、區別 集合是一種容器,數組也是一種容器 在Java編程中,裝各種各樣的對象(引用類型)的叫做容器。 為什麽出現集合類? 面向對象語言對事物的體現都是以對象的形式,所以為了方便對多個對象的操作

Java集合初探(二)Iterator(叠代器),collections,打包/解包(裝箱拆箱),泛型(Generic),comparable接口

基本 generate 等於 框架 ring bin list() each 是否 Iterator(叠代器) 所有實現了Collection接口的容器都有一個iterator方法, 用來返回一個實現了Iterator接口的對象 Iterator對象稱作叠代器, 用來

移位運算、Arrays中的copyOf、java.util.AbstractCollection、linux命令tail

xca eid width gte 技術分享 blank strac eba tail 移位運算:http://www.cnblogs.com/hongten/p/hongten_java_yiweiyunsuangfu.html。 ---------- Arrays中的c

Java命令學習系列jmap

.com respond 標識 config 一個bug running vivo huang 父類 jmap是JDK自帶的工具軟件,主要用於打印指定Java進程(或核心文件、遠程調試服務器)的共享對象內存映射或堆內存細節。可以使用jmap生成Heap Dump。 什麽

Java命令學習系列jstack

數據庫 get image for 線程調度 nbsp 額外 無限 其他 jstack是java虛擬機自帶的一種堆棧跟蹤工具。 功能 jstack用於生成java虛擬機當前時刻的線程快照。線程快照是當前java虛擬機內每一條線程正在執行的方法堆棧的集合,生成線程快照的主

2018年10月31日Java學習常用的命令列操作

1.常用的命令列操作 win+r調出並輸入cmd. 進入D盤:D:回車進入D盤:D:回車 D盤下的目錄DIR回車 建立目錄md 2018年10月31日 那麼建立了一個2018年10月31日的目錄(目前還在d盤目錄) 進入2018年10月31日的目錄 cd

java中的javap命令(工作中補充的知識)

背景: 上週針對某信得壓力測試demo進行場景復現,但是隻提供了class檔案,只能通過反編譯的軟體進行檢視,在復現的過程中報錯某某某行,這裡我以xx行代替,因為是class檔案,所以並不能確定具體到底是第幾行出現了問題。 解決: 在大神的幫助下,又學習到一個新

[零] Java 語言執行原理 JVM原理淺析 入門瞭解簡介 Java語言組成部分 javap命令使用

 The Java Virtual MachineJava虛擬機器是Java平臺的基石。是java實現硬體和作業系統的獨立性(也就是無關性),生成極小體積的編譯程式碼,以及保護使用者免受惡意程式攻擊的的關鍵技術組成部分。Java虛擬機器是一種抽象計算機器。像真正的計算機一樣,它有一個指令集以及在執行時各種記憶

java程式設計計算圓球體積(從命令窗輸入資料)

/* *已知圓球體積為4/3πr3,試編寫一個程式,輸入圓球半徑,經過計算輸出圓球的體積。 *從命令窗輸入 */ import java.util.Scanner; class volume{

Java常見命令jps

jps全名:Java Virtual Machine Process Status Tool作用:顯示當前系統使用者的Java程序情況及其Id號原理:Java程式在啟動以後,預設會在java.io.tmpdir指定的臨時資料夾目錄下生成一個類似於hsperfdata_字首的資

Java命令注入防護

1 Java中的命令注入 在Java中的Runtime.getRuntime本質就是使用ProcessBuilder,以ProcessBuilder裡用ProcessImpl,start 的一個子程序執行命令, Java的native呼叫 a.Windows是CreateP

Java命令列程式構建工具airlift使用分組(group)

閒話少說,直接上程式碼: package com.ilucky.druid.airlift.test2; import java.util.Arrays; import io.airlift.ai

Python 命令旅 —— 初探 argparse

『講解開源專案系列』啟動——讓對開源專案感興趣的人不再畏懼、讓開源專案的發起者不再孤單。跟著我們的文章,你會發現程式設計的樂趣、使用和發現參與開源專案如此簡單。歡迎聯絡我們給我們投稿,讓更多人愛上開源、貢獻開源~ 前言 你是否好奇過在命令列中敲入一段命令後,它是如何被解析執行的?是否考慮過由自己實現一個命

Java安全初探weblogic T3協議漏洞

# Java安全之初探weblogic T3協議漏洞 文章首發自安全客:[Java安全之初探weblogic T3協議漏洞](https://www.anquanke.com/post/id/226070) ## 0x00 前言 在反序列化漏洞裡面就經典的還是莫過於weblogic的反序列化漏洞,在we

Linux下常用命令sed學習總結

linux sed sed命令 正則表達式 sed總結 Sed功能說明:Sed是linux下一個強大的文本文件處理工具,通過對文件增加、刪除、查找、查詢操作,配合正則表達式以實現工作中的各種需求。同時也是一名運維人員必須掌握的核心技能。---------------------------

java基礎多線程

健壯性 等待 block running 調用 相同 空間 獲取 行程 參考博客 http://www.mamicode.com/info-detail-517008.html 1.進程和線程的區別   進程:每個進程都有獨立的代碼和數據空間(進程上下文),進程間的切換會有

清空文件內容命令echo和/dev/null區別?

linux 字符串 null 定向 我們知道清空文件內容有很多種方法我們只談論echo "" 和 /dev/null這兩種有什麽區別一、黑洞設備/dev/null是什麽?在 Linux 中, null 設備基本上被用來丟棄某個進程不再需要的輸出流,或者作為某個輸入流的空白文件,這些通常可以利用

Linux命令stty

repl 位置 而不是 connector 啟動 previous dsr 根據 pass 用途說明 stty命令用於顯示和修改終端行設置(change and print terminal line settings)。 常用參數 stty命令不帶參數可以打印終端行設置,