質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.48%

  • Java

    14094questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

逆コンパイルでコンストラクタのsuperを表示させたい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 2
  • VIEW 567

javaman

score 7

列挙型を調べていて下記のサイトで列挙型のソースを逆コンパイルしたソースが貼られていました。
https://qiita.com/Takmiy/items/5e47d87b5085de1ac37f
しかし、自分がコマンドプロンプトを使用して逆コンパイルするとこの様に表示されました。

元のソース

enum EnumTest2
{
    RED,
    BLUE,
    YELLOW;
    String color;
}


逆コンパイル後のソース

C:\JAVA\EnumTest2>javap -private EnumTest2
Compiled from "EnumTest2.java"
final class EnumTest2 extends java.lang.Enum<EnumTest2> {
  public static final EnumTest2 RED;
  public static final EnumTest2 BLUE;
  public static final EnumTest2 YELLOW;
  java.lang.String color;
  private static final EnumTest2[] $VALUES;
  public static EnumTest2[] values();
  public static EnumTest2 valueOf(java.lang.String);
  private EnumTest2();
  static {};
}


この様に自分が逆コンパイルするとコンストラクタのsuperの部分が省略されて表示されてしまいます。表示させる方法があったらご教授ください。

追記 使用しているバージョンは8です。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • coco_bauer

    2017/09/29 10:18

    お使いのJavaのバージョンは何ですか? 質問に書かれたURLの記事は、Java4以前とJava5以降のenumについて述べています。 現在(最新)のJavaはJava8で、Java5と挙動が異なると思われます。

    キャンセル

  • asahina1979

    2017/09/29 15:52

    パラメーターなしの super() は省略可能だから省略されてるだけじゃ

    キャンセル

  • javaman

    2017/09/29 16:12

    パラメーターprivate Stringを追加して自分でコンストラクタを追加した後逆コンパイルしたソースには "private EnumTest(java.lang.String);" と追加したパラメーターだけコンストラクタが表示されます。しかし、サイトの方はsuperの中身まで表示されています。

    キャンセル

回答 1

checkベストアンサー

+2

まず最初に、参照しておられるqiitaページの著者さんはjavapとは異なるデコンパイラー(逆アセンブルツール)を利用していると思います。javapはbyte codeのダンプは可能ですが、それに対応するjavaコードを表示する機能はなかったと思います。

ということを踏まえて・・・

自分が逆コンパイルするとコンストラクタのsuperの部分が省略されて表示されてしまいます。

superの部分というより処理コード自体が省略されています。それはjavapのバイトコード表示オプション「-c」を指定していないためです。

javap -p -c EnumTest2.class

とすると次が得られます(一部)

  private EnumTest2();
    Code:
       0: aload_0
       1: aload_1
       2: iload_2
       3: invokespecial #6 // Method java/lang/Enum."<init>":(Ljava/lang/String;I)V
       6: return

(前述のとおり)残念ながらjavapではjavaコードは得られませんが、それでもこのバイトコードを解釈すると

0: thisをpush
1: 第一引数をプッシュ
2: 第二引数をプッシュ
3: スーパークラス(java.lang.Enum)のコンストラクターを起動
6: return

なので、次に示すjavaコード相当であることが見て取れます。

リスト1:

private EnumTest2(String name, int ordinal) {
  super(name, ordinal);
}

デコンパイル結果をjavaコードとして得たい場合、どこかからデコンパイルツールを見つけてくるとよいでしょう。自分はIntelliJ IDEAのplug-in(Fernflower decompiler)を使ってます。使っているといってもIDEAを介して暗黙的に利用しているに過ぎませんが・・・
このFernflowerはplug-inとしてではなくスタンドアロンとしての利用もできるようですしjava8以降のbyte codeにも対応しているはずなので一応お奨めできると思います。デコンパイラーの中にはメンテが止まっていてjava8のbyte codeに対応していないものも見かけますので注意が必要です。


訂正:
コンストラクターなのにメソッドの型voidを書いていたので訂正しました orz
失礼しました。


補足:
Fernflowerを使うとリスト2が得られ、jadを使うとリスト1が得られるとのこと。

リスト2:

private EnumTest2() {}

よく考えてみるとこの点に気づけてなかったので補足します。

質問者さんの期待は「どのようなbyte codeとなるかを素朴にjavaコードで表現したもの」つまりリスト1であったわけですが、enumの場合、実際にコンストラクターに渡される最初の2つの引数(名前と順序数)はコンパイラーが内部的に生成するものであり、java言語仕様上はこれらの引数は明示的に記述できませんしsuperを呼び出すこともできないという点はご存知かと思います。つまり純粋にjavaとしての正しいソースコードを得るという意味ではjadよりむしろFernflowerの方が正しいということなのだと思います。jadを使うとbyte codeの生成の仕組みをストレートに知ることができるという利点がありますが、これを使うなら「必ずしもjavaの正しいソースコードが得られるわけではない」点に注意しておくべきなのでしょうね。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/10/05 11:00

    eclipseを使ってFernflower、JD-Coreでデコンパイルしてみましたが目的の結果が得られず最終的にjadを使ったらsuperの中身まで表示されました。ありがとうございました。

    キャンセル

  • 2017/10/05 11:22

    Fernflowerの綴り違っていて失礼しました。
    Fernflowerの結果の方がむしろ正しいのですが、そちらについてちょっとコメントしておきます。

    キャンセル

  • 2017/10/05 21:22

    追記ありがとうございます。
    自分の質問の仕方が悪かったのだと思います。
    恐らくコンパイル時に暗黙的に追加されるコードを知りたいと書いたらわかりやすかった気がします。jadとFernflowerや他のデコンパイラの仕様の違いは今後意識します。

    キャンセル

関連した質問

同じタグがついた質問を見る

  • Java

    14094questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。