AVAPはJDKに付属するツールです。 JDKインストールディレクトリで /binの下に見つけることができます。コードを逆コンパイルしたり、Javaコンパイラによって生成されたバイトコードを表示したり、コード実行プロセスを分析したり、JVM内の作業を理解したりできます。
以下には、Javapコマンドの一般的に使用されるオプションと関数の説明を示します。その他の機能については、より多くの機能をグーグルで検索してください。著者はそれについて詳しく説明しません。
使用概要
-ヘルプ
-l出力行と変数の表
-publicはパブリックメソッドとドメインのみを出力します
- 保護されているのは、公開クラスと保護されたクラスとメンバーのみを出力します
- パッケージはパッケージ、パブリックおよび保護されたクラス、およびメンバーのみを出力します。これはデフォルトです
-p -Privateすべてのクラスとメンバーを出力します
-S出力内部タイプの署名
-Cは、たとえばクラスの各メソッドに分解されたコードを出力します。JavaByteCodeを含む命令、
-verbose出力スタックサイズ、メソッドパラメーターの数
-CONSTANTS出力静的最終定数
ケーススタディ
Javapコマンドはクラスファイルを分解し、オプションに基づいて出力するものを決定します。オプションが使用されていない場合、Javapはクラスファイル、クラス内のパブリックドメイン、およびクラス内のすべてのメソッドにパッケージを出力します。 Javapは標準出力でそれらを出力します。この例を見て、最初に次のクラスをコンパイル(Javac)しましょう。
パッケージcom.thundersoft.metadata.test.kafka; Import org.apache.kafka.clients.consumer.consumerrecord; Import org.apache.kafka.clients.producer.kafkaproducer; Import org.apache.kafka.clients.producer.producer; org.apache.kafka.clients.producer.producerrecord; Import org.junit.test; Import java.util.arrays; Import java.util.properties; public class kafkatest {@test public public void testproducer(){properties = 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"); props.put( "value.serializer"、 "org.apache.kafka.common.serialization.stringserializer");プロデューサー<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(counterrecord <string、string> record: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を入力した後、出力の結果は次のとおりです
パブリッククラスcom.thundersoft.metadata.test.kafka.kafkatest {public com.thundersoft.metadata.test.kafka.kafkatest(); public void testProducer(); public void testkafkacosumer(); public static void main(java.lang.string []);}コード分析コンパイラ実行プロセスと組み合わせて
ここでは、メインメソッド内のコードロジックのみに焦点を当てます。メインメソッドコードは次のとおりです
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 []);コード: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 //方法Java/io/printStream.println:(i)v 15:return
上記のコードと同様に、ICONST_2とICONST_3はそれぞれ定数2と3を表します。 ILOAD_1およびILOAD_2は、それぞれ2つの通常の変数の定義を表します。ILOAD_1とILOAD_2はそれぞれ2つの変数のデータスタックへの負荷を表します。IMULは2つの変数の乗算操作を表し、結果は変数ISTORE_3に割り当てられ、最終的には結果が出力されます。
この簡単なコードを分析する過程で、ポスターはJVMコンピレーションコマンドのウェブサイトを発見し、JVMコマンドを共有しました。
要約します
著者は、それが運命にある人を助けることができることを望んで、それについて簡単なコード分析プロセスを実行しました。 Javapを使用して、コンパイラによるコンパイルされたバイトコードを逆コンパイルおよび表示できます。一般的に、あまり使用されませんが、Javap -Cがよく使用されます。このコマンドは、各メソッドによって実行されるJVM命令をリストするために使用されます。トリッキーなロジックエラーバグを解決することは良い選択です。さらに、バイトコードとソースコードの比較を通じて、JAVAのコンピレーション原則とコード実行プロセスを深く分析して、さまざまなJava原理レベルの問題を解決できます。