avap is a tool that comes with jdk. You can find it under /bin in the jdk installation directory. You can decompile the code, or view the bytecode generated by the java compiler, analyze the code execution process, and understand the work inside jvm.
The following lists the commonly used options and function descriptions of the Javap command. Please Google more functions for more functions. The author will not elaborate on it.
Usage summary
-help
-l Table of output rows and variables
-public only outputs public methods and domains
-protected only outputs public and protected classes and members
-package only outputs packages, public and protected classes and members, which is the default
-p -private outputs all classes and members
-s output internal type signature
-c outputs the decomposed code, for example, in each method in the class, an instruction containing java bytecode,
-verbose output stack size, number of method parameters
-constants Output static final constants
Case Study
The javap command decomposes a class file, and it determines what to output based on options. If options are not used, then javap will output the package in the class file, protected and public domains in the class, and all methods in the class. Javap will output them on standard output. Let’s look at this example and first compile (javac) the following class.
package 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;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"); 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); }}After typing javap KafkaTest on the command line, the output result is as follows
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[]);}Combined with code analysis compiler execution process
Here we only focus on the code logic inside the main method. The main method code is as follows
public static void main(String[] args) { int a = 2; int b = 3; int sum = a*b; System.out.println(sum); }After typing javap -c KafkaTest on the command line, the output result is as follows
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
As in the above code, iconst_2 and iconst_3 represent constants 2 and 3 respectively. iload_1 and iload_2 respectively represent the definition of two ordinary variables, iload_1 and iload_2 respectively represent the loading of two variables into the data stack, imul represents the multiplication operation of the two variables, and the result is assigned to the variable istore_3, and finally the result is output and the program returns.
During the process of analyzing this simple code, the poster discovered a website for jvm compilation commands and shared the jvm commands.
Summarize
The author has done a simple code analysis process on it, hoping that it can help those who are destined to be. Javap can be used to decompile and view compiled bytecode by the compiler. Generally, not much is used, but Javap -c is often used. This command is used to list the JVM instructions executed by each method. It is a good choice to solve tricky logic error bugs. In addition, through the comparison of bytecode and source code, we can deeply analyze the compilation principles and code execution process of java to solve various Java principle-level problems.