
Narzędzie pozwala na deasemblację jednego lub więcej plików klas. Deasemblacja polega na przekształceniu binariów w tekst i pokazaniu kodu bajtowego. Komplet informacji o JVM i kodzie bajtowym możesz znaleźć w specyfikacjach Oracle. To co otrzymujemy na wyjściu (stdout) zależy od ustawionych opcji. Jeżeli żadna opcja nie jest ustawiona polecenie javap drukuje pola oznaczone jako public lub jako protected oraz metody.
Składnia
javap [options] classes
[options]
| [options] | Opis |
|---|---|
-help albo --help albo -? |
Drukuje tekst pomocy dla javap |
-version |
Drukuje informację o wersji narzędzia |
-verbose albo -v |
Drukuje dodatkowe informacje o wybranych klasach |
-l |
Drukuje linię i tabelę zmiennych lokalnych |
-public |
Drukuje tylko publiczne klasy i członki (members) |
-protected |
Drukuje tylko chronione klasy i członki (members) |
| -package | Drukuje klasy i członki pakietowe chronione i publiczne |
-private albo -p |
Drukuje wszystkie klasy i czlonki (members) |
-c |
Drukuje deasemblowany kod np. instrukcje, które tworzą kod bajtowy dla każdej metody w klasie |
-s |
Drukuje wewnętrzne sygnatury typów |
-sysinfo |
Pokazuje systemowe informacje o przetwarzanej klasie (ścieżka, wielkość, data, skrót MD5) |
-constants |
Pokazuje stałe oznaczone final constant |
--module module albo-m module |
Moduł zawierający klasy do deasemblacji |
--module-path path |
Ścieżka do modułów aplikacji |
--system jdk |
Ścieżka do modułów systemowych |
--class-path path albo-classpath path albo-cp path |
Ścieżka, której javap użyje do znalezienia plików klas użytkownika. Użycie tej opcji nadpisuje domyślną lub środowiskową ( CLASSPATH) zmienną, jeśli jest ustawiona |
--bootclasspath path |
Nadpisuje położenie plików klas wstępnego ładowania (bootstrap) |
-Joption |
Specyfikuje opcje dla JVM (zostaną omówione przy omawianiu narzędzia java). Na przykład:
javap -J-version
javap -J-Djava.security.manager ↩
-J-Djava.security.policy=MyPolicy MyClassName
|
classes
Specyfikuje jedną lub więcej klas oddzielonych spacjami do przetworzenia adnotacji.
Klasa może być znaleziona w ścieżce klas po:
- nazwie
path/to/MyClass.class - URL-u
jar:file:///path/to/MyJar.jar!/mypkg/MyClass.class - kwalifikowanej nazwie klasy
java.lang.Object
Narzędzie nie rozpoznaje wielowersyjnych (multirelease) plików JAR. Jeżeli użyjemy 'ścieżkowej’ formy polecenia zobaczymy podstawowe wejścia (base entry) we wszystkich plikach JAR, multiwersyjnych czy nie.
Aby deasemblować klasy z danej wersji należy użyć polecenia w formie URL.
Przykład (linia poleceń)
W Windows 10, JDK 12.0.2, IntelliJ IDEA mamy projekt 'animations’. W projekcie mamy jeden moduł 'animation01′ (Rys 5).

Tworzymy plik animation01.jar. Jak przygotowywać pliki JAR pokażę przy omawianiu narzędzia JDK jar.
Pliki źródłowe + JAR możesz ściągnąć stąd: animation01
Plik JAR umieszczamy w folderze C:/assets/javap/
Z wiersza poleceń wydajemy polecenie:
C:\WINDOWS\system32>javap -p -c -s -constants jar:file:///C:/assets/javap/animation01.jar!/animation01/Card.class
Otrzymujemy:
Microsoft Windows [Version 10.0.18363.836]
(c) 2019 Microsoft Corporation. Wszelkie prawa zastrzeżone.
Active code page: 65001
C:\WINDOWS\system32>javap -p -c -s -constants jar:file:///C:/assets/javap/animation01.jar!/animation01/Card.class
Compiled from "Card.java"
public class animation01.Card extends javax.swing.JComponent {
private static final long serialVersionUID = 5586338595500806338l;
descriptor: J
private static final int XSIZE = 182;
descriptor: I
private static final int YSIZE = 335;
descriptor: I
private final java.awt.image.BufferedImage bimage;
descriptor: Ljava/awt/image/BufferedImage;
public animation01.Card(java.lang.String);
descriptor: (Ljava/lang/String;)V
Code:
0: aload_0
1: invokespecial #1 // Method javax/swing/JComponent."<init>":()V
4: aload_0
5: aload_1
6: invokestatic #2 // Method fileToBimage3:(Ljava/lang/String;)Ljava/awt/image/BufferedImage;
9: putfield #3 // Field bimage:Ljava/awt/image/BufferedImage;
12: aload_0
13: aconst_null
14: invokevirtual #4 // Method setLayout:(Ljava/awt/LayoutManager;)V
17: aload_0
18: iconst_0
19: iconst_0
20: sipush 182
23: sipush 335
26: invokevirtual #6 // Method setBounds:(IIII)V
29: aload_0
30: new #7 // class java/awt/Dimension
33: dup
34: sipush 182
37: sipush 335
40: invokespecial #8 // Method java/awt/Dimension."<init>":(II)V
43: invokevirtual #9 // Method setPreferredSize:(Ljava/awt/Dimension;)V
46: return
public void paintComponent(java.awt.Graphics);
descriptor: (Ljava/awt/Graphics;)V
Code:
0: aload_0
1: aload_1
2: invokespecial #10 // Method javax/swing/JComponent.paintComponent:(Ljava/awt/Graphics;)V
5: aload_1
6: checkcast #11 // class java/awt/Graphics2D
9: astore_2
10: aload_2
11: aload_0
12: getfield #3 // Field bimage:Ljava/awt/image/BufferedImage;
15: iconst_0
16: iconst_0
17: sipush 182
20: sipush 335
23: aload_0
24: invokevirtual #12 // Method java/awt/Graphics2D.drawImage:(Ljava/awt/Image;IIIILjava/awt/image/ImageObserver;)Z
27: pop
28: return
private static java.awt.image.BufferedImage fileToBimage3(java.lang.String);
descriptor: (Ljava/lang/String;)Ljava/awt/image/BufferedImage;
Code:
0: aload_0
1: invokestatic #13 // Method loadImage:(Ljava/lang/String;)Ljava/awt/Image;
4: astore_1
5: invokestatic #14 // Method java/awt/GraphicsEnvironment.getLocalGraphicsEnvironment:()Ljava/awt/GraphicsEnvironment;
8: invokevirtual #15 // Method java/awt/GraphicsEnvironment.getDefaultScreenDevice:()Ljava/awt/GraphicsDevice;
11: invokevirtual #16 // Method java/awt/GraphicsDevice.getDefaultConfiguration:()Ljava/awt/GraphicsConfiguration;
14: astore_3
15: aload_3
16: aload_1
17: aconst_null
18: invokevirtual #17 // Method java/awt/Image.getWidth:(Ljava/awt/image/ImageObserver;)I
21: aload_1
22: aconst_null
23: invokevirtual #18 // Method java/awt/Image.getHeight:(Ljava/awt/image/ImageObserver;)I
26: invokevirtual #19 // Method java/awt/GraphicsConfiguration.createCompatibleImage:(II)Ljava/awt/image/BufferedImage;
29: astore_2
30: aload_2
31: invokevirtual #20 // Method java/awt/image/BufferedImage.getGraphics:()Ljava/awt/Graphics;
34: aload_1
35: iconst_0
36: iconst_0
37: aconst_null
38: invokevirtual #21 // Method java/awt/Graphics.drawImage:(Ljava/awt/Image;IILjava/awt/image/ImageObserver;)Z
41: pop
42: aload_2
43: areturn
private static java.awt.Image loadImage(java.lang.String);
descriptor: (Ljava/lang/String;)Ljava/awt/Image;
Code:
0: invokestatic #22 // Method java/awt/Toolkit.getDefaultToolkit:()Ljava/awt/Toolkit;
3: aload_0
4: invokevirtual #23 // Method java/awt/Toolkit.getImage:(Ljava/lang/String;)Ljava/awt/Image;
7: astore_1
8: new #24 // class java/awt/MediaTracker
11: dup
12: new #25 // class javax/swing/JPanel
15: dup
16: invokespecial #26 // Method javax/swing/JPanel."<init>":()V
19: invokespecial #27 // Method java/awt/MediaTracker."<init>":(Ljava/awt/Component;)V
22: astore_2
23: aload_2
24: aload_1
25: iconst_0
26: invokevirtual #28 // Method java/awt/MediaTracker.addImage:(Ljava/awt/Image;I)V
29: aload_2
30: iconst_0
31: invokevirtual #29 // Method java/awt/MediaTracker.waitForID:(I)V
34: goto 43
37: astore_3
38: aload_3
39: invokevirtual #31 // Method java/lang/InterruptedException.getMessage:()Ljava/lang/String;
42: pop
43: aload_1
44: areturn
Exception table:
from to target type
29 34 37 Class java/lang/InterruptedException
}
C:\WINDOWS\system32>
Przykład (ToolProvider)
Polecenie możemy wykonać z poziomu klasy Java (javap.TP_javap)
package javap; import java.util.Optional; import java.util.function.Consumer; import java.util.spi.ToolProvider; public class TP_javap { public static void main(String[] args){ Optional<ToolProvider> javap = ToolProvider.findFirst("javap"); javap.ifPresent(new Consumer<ToolProvider>() { @Override public void accept(ToolProvider toolProvider) { toolProvider.run(System.out, System.err, "-p", "-c", "-s", "-constants", "jar:file:///C:/assets/javap/animation01.jar!/animation01/Card.class"); } }); } }
Wynik wykonania jest dokładnie identyczny jak w przykładzie użycia przy pomocy linii poleceń.
Przykład (ProcessBuilder)
Polecenie możemy wykonać z poziomu klasy Java (javap.PB_javap)
package javap; import java.io.BufferedReader; import java.io.IOException; public class PB_javap { public static void main(String[] args){ try { ProcessBuilder pb = new ProcessBuilder(); pb.command("javap", "-p", "-c", "-s", "-constants", "jar:file:///C:/assets/javap/animation01.jar!/animation01/Card.class"); Process p = pb.start(); BufferedReader r = p.inputReader(); String line; while ((line = r.readLine()) != null) { System.out.println(line); } int exitCode = p.waitFor(); System.out.println("\nExited with code : " + exitCode); r.close(); p.destroy(); } catch (IOException | InterruptedException e) { e.printStackTrace(); } } }
Wynik wykonania jest dokładnie identyczny jak w przykładzie użycia przy pomocy linii poleceń.
