読者です 読者をやめる 読者になる 読者になる
無料で使えるシステムトレードフレームワーク「Jiji」 をリリースしました!

・OANDA Trade APIを利用した、オープンソースのシステムトレードフレームワークです。
・自分だけの取引アルゴリズムで、誰でも、いますぐ、かんたんに、自動取引を開始できます。

Javaクラス解析機を作る 2日目

Ruby Java クラス解析機

引き続き、まったり実装。

  • フィールド情報の読み込みまで対応
    • ただし、フィールドの属性(attribute)は未対応。
  • クラス構成をいろいろ変更。constantとかは別クラスとした。

現在の読み込み対応データ

★付きが今日対応したモノ。

クラスデータ
名称 サイズ 説明
magic 4byte クラスファイルを識別するためのマジックナンバー。0xCAFEBABEが入る。
minor_version 2byte クラスのマイナーバージョン
major_version 2byte クラスのメジャーバージョン
constant_pool_count 2byte constant_pool (クラス名メソッド名などの定数が格納されるテーブル)の数
constant_pool 可変 クラス名メソッド名などの定数が格納されるテーブル。constant_pool_count-1個のconstant_poolが並ぶ。「文字列」や「Class情報」など種類がいくつかあって、それぞれデータ形式/サイズが異なる。
access_flags 2byte クラス/インターフェイスのアクセス権限情報
this_class 2byte このクラスファイルで定義されているクラスを示すconstant_poolのid。
★super_class 2byte このクラスファイルで定義されているクラスの親クラスを示すconstant_poolのid。
★interfaces_count 2byte 実装しているインターフェイスの数。
★interfaces 可変(2byte*interfaces_count) 実装しているインターフェイスを示すconstant_poolのid。interfaces_count数だけ続く。
★fields_count 2byte クラス/インターフェイスで定義されているフィールドの数。
★field_info 可変 クラス/インターフェイスで定義されているフィールド。データ形式は「フィールドデータ」を参照。fields_count数だけ続く。
フィールドデータ
名称 サイズ 説明
access_flags 2byte フィールドのアクセス権限情報
★name_index 2byte フィールド名を示すconstant_poolのid
★descriptor_index 2byte フィールドの型の文字列表現を示すconstant_poolのid
attributes_count 2byte フィールドに付加された属性の数
attribute_info 可変 フィールドの属性。定数の値やdeplicatedの情報なんかが属性として指定されるらしい。attributes_count数だけ続く

ここまでの解析コード

長くなってきたので、リンクで。
→Javaクラス解析機 2008/04/10

動作サンプル

ターゲットのJavaクラス(のソース)

package com.example;

import java.io.Serializable;

/**
 * 猫。
 *
 * @version $Revision:$
 * @author  $Author:$
 */
public class Kitten implements Serializable {

    /**
     * 名前
     */
    private String name = "";

    /**
     * 年齢
     */
    private int age = 0;

    /**
     * コンストラクタ
     */
    public Kitten (){}

    /**
     * コンストラクタ
     *
     * @param name
     *        名前
     * @param age
     *        年齢
     */
    public Kitten (
        String name,
        int age ) {
        this.name = name;
        this.age = age;
    }

    /**
     * 名前を取得する。
     * @return 名前
     */
    public String getName () {
        return name;
    }
    /**
     * 名前を設定する。
     * @param name 名前
     */
    public void setName ( String name ) {
        this.name = name;
    }

    /**
     * 年齢を取得する。
     * @return 年齢
     */
    public int getAge () {
        return age;
    }
    /**
     * 年齢を設定する。
     * @param age 年齢
     */
    public void setAge ( int age ) {
        this.age = age;
    }
    /**
     * 鳴く
     */
    public void meow( ) {
        System.out.println( "meow!" );
    }
}

解析!

open( "./Kitten.class", "r+b" ) {|io|
  jc = Java::JavaClass.new io
  puts jc.to_s
}

実行結果です。

// version 49.0
public super class com.example.Kitten 
extends java.lang.Object 
implements java.io.Serializable {

    private java.lang.String name;
    private int age;

}

access_flagsの「super」ってなんだろ?