Heim Java javaLernprogramm Beispiel einer Methode zum Implementieren eines Klassenparsers in Java

Beispiel einer Methode zum Implementieren eines Klassenparsers in Java

Sep 15, 2017 am 10:16 AM
class java 方法

In diesem Artikel werden hauptsächlich Beispiele für Java-Klassenparser-Implementierungsmethoden durch die Analyse von Klassendateien vorgestellt. Es hat einen gewissen Referenzwert und Freunde, die es brauchen, können mehr darüber erfahren.

Kürzlich schreibe ich ein privates Projekt namens ClassAnalyzer. Der Zweck von ClassAnalyzer besteht darin, uns ein tiefgreifendes Verständnis des Designs und der Struktur von Java-Klassendateien zu vermitteln. Das Hauptgerüst und die Grundfunktionen wurden fertiggestellt und einige detaillierte Funktionen werden in Zukunft hinzugefügt. Tatsächlich stellt JDK bereits das Befehlszeilentool javap zum Dekompilieren von Klassendateien bereit, aber dieser Artikel wird meine Idee der Implementierung des Parsers klären.

Klassendatei

Als Träger von Klassen- oder Schnittstelleninformationen definiert jede Klassendatei vollständig eine Klasse. Damit Java-Programme „einmal geschrieben und überall ausgeführt werden“ können, enthält die Java Virtual Machine-Spezifikation strenge Vorschriften für Klassendateien. Die grundlegende Dateneinheit, aus der eine Klassendatei besteht, sind Bytes. Zwischen diesen Bytes gibt es keine Trennzeichen. Dadurch werden in der gesamten Klassendatei fast alle für den Programmbetrieb erforderlichen Daten dargestellt multiple Dargestellt durch aufeinanderfolgende Bytes.

Gemäß der Java Virtual Machine-Spezifikation verwendet die Klassendatei eine Pseudostruktur, die der C-Sprachstruktur ähnelt, um Daten zu speichern. In dieser Pseudostruktur gibt es nur zwei Datentypen: vorzeichenlose Zahlen und Tische. Die Java Virtual Machine-Spezifikation definiert u1, u2, u4 und u8 zur Darstellung vorzeichenloser Zahlen von 1 Byte, 2 Byte, 4 Byte und 8 Byte. Zur Beschreibung von Zahlen und Indizes können Referenzen, Mengen oder Zeichenfolgen verwendet werden. Eine Tabelle ist ein zusammengesetzter Datentyp, der aus mehreren vorzeichenlosen Zahlen oder anderen Tabellen als Datenelementen besteht. Die Tabelle wird verwendet, um Daten mit einer hierarchischen zusammengesetzten Struktur zu beschreiben, sodass die gesamte Klassendatei im Wesentlichen eine Tabelle ist. In ClassAnalyzer entsprechen Byte, Short, Int und Long den Datentypen u1, u2, u4 und u8. Die Klassendatei wird als die folgende Java-Klasse beschrieben.


public class ClassFile {
 public U4 magic;       // magic
 public U2 minorVersion;      // minor_version
 public U2 majorVersion;      // major_version
 public U2 constantPoolCount;    // constant_pool_count
 public ConstantPoolInfo[] cpInfo;   // cp_info
 public U2 accessFlags;      // access_flags
 public U2 thisClass;      // this_class
 public U2 superClass;      // super_class
 public U2 interfacesCount;     // interfaces_count
 public U2[] interfaces;      // interfaces
 public U2 fieldsCount;      // fields_count
 public FieldInfo[] fields;     // fields
 public U2 methodsCount;      // methods_count
 public MethodInfo[] methods;    // methods
 public U2 attributesCount;     // attributes_count
 public BasicAttributeInfo[] attributes;  // attributes
}
Nach dem Login kopieren

So analysieren Sie die verschiedenen Datenelemente, aus denen die Klassendatei besteht, z. B. magische Zahlen und Klassendateiversionen sowie andere Datenelemente und Zugriffsflags , Klassenindex, übergeordneter Klassenindex, sie belegen eine feste Anzahl von Bytes in jeder Klassendatei, und beim Parsen muss nur die entsprechende Anzahl von Bytes gelesen werden. Darüber hinaus müssen hauptsächlich vier Teile flexibel gehandhabt werden: Konstantenpool, Feldtabellensammlung, Methodentabellensammlung und Attributtabellensammlung. Felder und Methoden können ihre eigenen Attribute haben, und die Klasse selbst verfügt auch über entsprechende Attribute. Daher umfasst das Parsen der Feldtabellensammlung und Methodentabellensammlung auch das Parsen der Attributtabelle.

Der Konstantenpool nimmt einen großen Teil der Daten in der Klassendatei ein und wird zum Speichern aller Konstanteninformationen verwendet, einschließlich numerischer und Zeichenfolgenkonstanten, Klassennamen, Schnittstellennamen, Feldnamen, Methodennamen, usw. Die Java Virtual Machine-Spezifikation definiert mehrere Konstantentypen, von denen jeder seine eigene Struktur hat. Der Konstantenpool selbst ist eine Tabelle, und beim Parsen sind mehrere Punkte zu beachten.


Jeder Konstantentyp wird durch ein Tag vom Typ u1 identifiziert.


Die im Header angegebene Konstantenpoolgröße (constantPoolCount) ist um 1 größer als der tatsächliche Wert. Wenn beispielsweise konstantPoolCount gleich 47 ist, gibt es 46 Konstanten im Konstantenpool.


Der Indexbereich des Konstantenpools beginnt bei 1. Wenn beispielsweise „constantPoolCount“ gleich 47 ist, beträgt der Indexbereich des Konstantenpools 1 bis 46. Der Zweck des Designers, Element 0 leer zu lassen, besteht darin, auszudrücken, dass „kein konstantes Poolelement referenziert wird“.


Die Struktur der Konstante CONSTANT_Utf8_info enthält ein Tag vom Typ u1, eine Länge vom Typ u2 und Bytes, die aus Längen-U1-Typen bestehen. Die kontinuierlichen Daten der Längenbytes sind kontinuierliche Daten mit MUTF-8 (. Modifizierte UTF-8)-codierte Zeichenfolge. MUTF-8 ist nicht mit UTF-8 kompatibel. Es gibt zwei Hauptunterschiede: Erstens wird das Nullzeichen in 2 Bytes (0xC0 und 0x80) codiert; zweitens werden die Zusatzzeichen in Ersatzzeichen aufgeteilt und gemäß UTF separat codiert -16, die entsprechenden Details finden Sie hier (Variante UTF-8).


Attributtabellen werden verwendet, um Informationen zu beschreiben, die für bestimmte Szenarios spezifisch sind. Klassendateien, Feldtabellen und Methodentabellen verfügen alle über entsprechende Attributtabellensätze. Die Java Virtual Machine-Spezifikation definiert eine Vielzahl von Attributen, und ClassAnalyzer implementiert derzeit das Parsen häufig verwendeter Attribute. Im Gegensatz zu Datenelementen vom Typ Konstante verfügen Attribute nicht über ein Tag zur Identifizierung des Attributtyps, aber jedes Attribut enthält einen attribute_name_index vom Typ u2, der auf eine Konstante vom Typ CONSTANT_Utf8_info im Konstantenpool verweist, die den Namen des Attributs enthält. Beim Parsen von Attributen erkennt ClassAnalyzer den Typ des Attributs anhand des Attributnamens, der der Konstante entspricht, auf die durch attribute_name_index verwiesen wird.


Feldtabelle wird verwendet, um in einer Klasse oder Schnittstelle deklarierte Variablen zu beschreiben. Zu den Feldern gehören Variablen auf Klassenebene und Variablen auf Instanzebene. Die Struktur der Feldtabelle umfasst einen u2-Typ access_flags, einen u2-Typ name_index, einen u2-Typ descriptor_index, einen u2-Typ attributes_count und attributes_count attributes_info-Typattribute. Wir haben das Parsing von Attributtabellen bereits eingeführt. Die Parsing-Methode von Attributen stimmt mit der Parsing-Methode von Attributtabellen überein.


Class的文件方法表采用了和字段表相同的存储格式,只是access_flags对应的含义有所不同。方法表包含着一个重要的属性:Code属性。Code属性存储了Java代码编译成的字节码指令,在ClassAnalyzer中,Code对应的Java类如下所示(仅列出了类属性)


public class Code extends BasicAttributeInfo {
 private short maxStack;
 private short maxLocals;
 private long codeLength;
 private byte[] code;
 private short exceptionTableLength;
 private ExceptionInfo[] exceptionTable;
 private short attributesCount;
 private BasicAttributeInfo[] attributes;
 ...
 private class ExceptionInfo {
  public short startPc;
  public short endPc;
  public short handlerPc;
  public short catchType;
   ...
 }
}
Nach dem Login kopieren

在Code属性中,codeLength和code分别用于存储字节码长度和字节码指令,每条指令即一个字节(u1类型)。在虚拟机执行时,通过读取code中的一个个字节码,并将字节码翻译成相应的指令。另外,虽然codeLength是一个u4类型的值,但是实际上一个方法不允许超过65535条字节码指令。

代码实现

ClassAnalyzer的源码已放在了GitHub上。在ClassAnalyzer的README中,我以一个类的Class文件为例,对该Class文件的每个字节进行了分析,希望对大家的理解有所帮助。

Das obige ist der detaillierte Inhalt vonBeispiel einer Methode zum Implementieren eines Klassenparsers in Java. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Wie man alles in Myrise freischaltet
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Quadratwurzel in Java Quadratwurzel in Java Aug 30, 2024 pm 04:26 PM

Leitfaden zur Quadratwurzel in Java. Hier diskutieren wir anhand eines Beispiels und seiner Code-Implementierung, wie Quadratwurzel in Java funktioniert.

Perfekte Zahl in Java Perfekte Zahl in Java Aug 30, 2024 pm 04:28 PM

Leitfaden zur perfekten Zahl in Java. Hier besprechen wir die Definition, Wie prüft man die perfekte Zahl in Java?, Beispiele mit Code-Implementierung.

Armstrong-Zahl in Java Armstrong-Zahl in Java Aug 30, 2024 pm 04:26 PM

Leitfaden zur Armstrong-Zahl in Java. Hier besprechen wir eine Einführung in die Armstrong-Zahl in Java zusammen mit einem Teil des Codes.

Zufallszahlengenerator in Java Zufallszahlengenerator in Java Aug 30, 2024 pm 04:27 PM

Leitfaden zum Zufallszahlengenerator in Java. Hier besprechen wir Funktionen in Java anhand von Beispielen und zwei verschiedene Generatoren anhand ihrer Beispiele.

Weka in Java Weka in Java Aug 30, 2024 pm 04:28 PM

Leitfaden für Weka in Java. Hier besprechen wir die Einführung, die Verwendung von Weka Java, die Art der Plattform und die Vorteile anhand von Beispielen.

Smith-Nummer in Java Smith-Nummer in Java Aug 30, 2024 pm 04:28 PM

Leitfaden zur Smith-Zahl in Java. Hier besprechen wir die Definition: Wie überprüft man die Smith-Nummer in Java? Beispiel mit Code-Implementierung.

Fragen zum Java Spring-Interview Fragen zum Java Spring-Interview Aug 30, 2024 pm 04:29 PM

In diesem Artikel haben wir die am häufigsten gestellten Fragen zu Java Spring-Interviews mit ihren detaillierten Antworten zusammengestellt. Damit Sie das Interview knacken können.

Brechen oder aus Java 8 Stream foreach zurückkehren? Brechen oder aus Java 8 Stream foreach zurückkehren? Feb 07, 2025 pm 12:09 PM

Java 8 führt die Stream -API ein und bietet eine leistungsstarke und ausdrucksstarke Möglichkeit, Datensammlungen zu verarbeiten. Eine häufige Frage bei der Verwendung von Stream lautet jedoch: Wie kann man von einem Foreach -Betrieb brechen oder zurückkehren? Herkömmliche Schleifen ermöglichen eine frühzeitige Unterbrechung oder Rückkehr, aber die Stream's foreach -Methode unterstützt diese Methode nicht direkt. In diesem Artikel werden die Gründe erläutert und alternative Methoden zur Implementierung vorzeitiger Beendigung in Strahlverarbeitungssystemen erforscht. Weitere Lektüre: Java Stream API -Verbesserungen Stream foreach verstehen Die Foreach -Methode ist ein Terminalbetrieb, der einen Vorgang für jedes Element im Stream ausführt. Seine Designabsicht ist

See all articles