なぜバイトコードを学ぶために皆をお勧めしますでしょうか?

ビデオのサポート:

なぜJavaのバイトコードを学ぶお勧めします

https://www.bilibili.com/video/av77600176/

 

I.背景

本論文では、説明しますなぜJVMバイトコードを学びますか?

通常より少ないと発展、そしてこれは学習延期していない学習することはありませんので、多くの人々が、への必要性を感じないかもしれません。

しかし、ここではその感情を共有するために、あること、常にここの人々は、彼らの知識とスキルを習得されているに応じて問題を解決します。

ここでは、時にはあなたがそれを習得していないという理由だけではほとんど役に立たない技術を感じ、パラドックスである、あなたはそれはあなたが使用すると思わないだろう場面に遭遇使用することができます

 

1.1の条件での生活の観点から

あなたは非コンピュータ科学の学生であれば、あなたの先生はあなたの本のいくつかの写真を与え、3,000の単語について、あなたはテキストに印刷してみましょう。

あなたは、食事は午後に行われたノックアウトパチパチ、コンピュータの電源をオンにします。

あなたは、音声入力を知っている場合、あなたは、音声入力の方法により取得するには30分です。

あなたは写真のOCRテキスト認識を知っている場合は、5分を得ることができます。

 

別の方法は、効果が全く異なるもたらしました。しかし、ほとんどの恐ろしいところは、入力音声はありませんかOCRは、あなたが感じるあまり漢ではないということです。

OCRの認識は間違いなくあなたのタイピング速度はに追いつくために指すことができます改善されていません。

1.2学習のJava角度

多くの人々は、Baiduのに主に依存している学ぶブログ、ビデオ、書籍を頼りに依存し、様々な品質のこれらのデータ、および他の人が理解した後に結果です。

たとえば、あなたは通常、ソースコードが表示されないあなたが学ぶように、あなたはめったにソース素材にできなくなり、唯一のブログ、書籍、動画などを頼ることができます。

あなたは通常、ソースコードを見てみたい場合は、ソースコードの独自の理解を持つことになります、あなたが学習に役立つソースコードがたくさんあることがわかります。

あなたは通常、抗逆コンパイルしてコンパイルしないとした場合、あなたはより多くのソースコード、デバッグ、および他の依存学習知識を頼る必要がなく、バイトコードレベルから学び、知識を理解します。

あなたはゆっくりと熟練した仮想マシン命令を読んだとき、あなたはあなたのより多くの知識を学ぶための方法を見つけるだろう。

 

第二に、なぜバイトコードを学ぶ必要があります

2.1人々は常に快適ゾーンを残すには消極的です

新しい知識の学習に多くの人々は、常に本能的に競合します。「後日「を、無益な学習」、「そのよう未満であるとして」学ばないさまざまな理由があります。」

でも、私はそれは時間の無駄だと思いました。

 

2.2なぜバイトコードを学びますか?

最近しかし熟練していない、いくつかの時間のJVMバイトコードについて学んだが、それはあまり困難であったバイトコードを読みます。

それは、Javaを学ぶための知識の源より深いレベルことができるので、なぜバイトコードの学習をお勧めします。

、しかし、それはあなたのすべての問題は、バイトコードを解決するための知識と一緒にいるとは考えにくいものの学ぶための方法を提供します。

たとえば、あなたがより良い言語機能や多型のより良い理解の背後にJava構文と文法糖の種々の原理を理解することができ、バイトコード学習によって。

 

例えば第三に、

ここでバイトコードを学習の効果を説明するために簡単な例を挙げています。

3.1例

3.1.1シンタックスシュガー

public class ForEachDemo {

    public static void main(String[] args) {

        List<String> data = new ArrayList<>();
        data.add("a");
        data.add("b");
        for (String str : data) {
            System.out.println(str);
        }
    }
}

コンパイラ:javacのForEachDemo.java

分解:てjavap -c ForEachDemo

public class com.imooc.basic.learn_source_code.local.ForEachDemo {
  public com.imooc.basic.learn_source_code.local.ForEachDemo();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: new           #2                  // class java/util/ArrayList
       3: dup
       4: invokespecial #3                  // Method java/util/ArrayList."<init>":()V
       7: astore_1
       8: aload_1
       9: ldc           #4                  // String a
      11: invokeinterface #5,  2            // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
      16: pop
      17: aload_1
      18: ldc           #6                  // String b
      20: invokeinterface #5,  2            // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z
      25: pop
      26: aload_1
      27: invokeinterface #7,  1            // InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
      32: astore_2
      33: aload_2
      34: invokeinterface #8,  1            // InterfaceMethod java/util/Iterator.hasNext:()Z
      39: ifeq          62
      42: aload_2
      43: invokeinterface #9,  1            // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
      48: checkcast     #10                 // class java/lang/String
      51: astore_3
      52: getstatic     #11                 // Field java/lang/System.out:Ljava/io/PrintStream;
      55: aload_3
      56: invokevirtual #12                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      59: goto          33
      62: return
}

我々は明確に(あなたがソースバイトコードに同等応じて書いてみることができます)、対応するJavaソースコードから、foreachループを達成するためのイテレータを使用しての下、あるいは逆の脳の塗りつぶしを見ることができます。

 

 

一つの問題は、ソースコードを読むために3.1.2に遭遇しました

私たちは、多くの場合、ソースコードを読んで、次のようなこのようなアプローチが発生します。

org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext#startWebServer

	private WebServer startWebServer() {
		WebServer webServer = this.webServer;
		if (webServer != null) {
			webServer.start();
		}
		return webServer;
	}

ローカル変数や関数内に同じ名前のメンバ変数の宣言、その後、ローカル変数に割り当てメンバ変数は、使用することを行きます。

一見小さな詳細は、最適化のアイデアを意味します。

(一部の人々は、記事の一部が言及読んだことがあり、我々はあなたがするか?表示されない場合は、知識が?ますポスト見なきゃ、なぜしかし、より多くの人々がどのような最適化を理解していない可能性が)。

 

3.2アナログ

ここでは一般的なシンタックスシュガーがあまりにも多くの拡張を行うことはありませんが、我々は、第2の最適化の例についてお話します。

上記模倣文言の例

public class LocalDemo {

    private List<String> data = new ArrayList<>();

    public void someMethod(String param) {
        List<String> data = this.data;
        if (data != null && data.size() > 0 && data.contains(param)) {
            System.out.println(data.indexOf(param));
        }

    }

}

コンパイラ:javacのLocalDemo.java

分解:てjavap -c LocalDemo

public class com.imooc.basic.learn_source_code.local.LocalDemo {
  public com.imooc.basic.learn_source_code.local.LocalDemo();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: aload_0
       5: new           #2                  // class java/util/ArrayList
       8: dup
       9: invokespecial #3                  // Method java/util/ArrayList."<init>":()V
      12: putfield      #4                  // Field data:Ljava/util/List;
      15: return

  public void someMethod(java.lang.String);
    Code:
       0: aload_0
       1: getfield      #4                  // Field data:Ljava/util/List;
       4: astore_2
       5: aload_2
       6: ifnull        41
       9: aload_2
      10: invokeinterface #5,  1            // InterfaceMethod java/util/List.size:()I
      15: ifle          41
      18: aload_2
      19: aload_1
      20: invokeinterface #6,  2            // InterfaceMethod java/util/List.contains:(Ljava/lang/Object;)Z
      25: ifeq          41
      28: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;
      31: aload_2
      32: aload_1
      33: invokeinterface #8,  2            // InterfaceMethod java/util/List.indexOf:(Ljava/lang/Object;)I
      38: invokevirtual #9                  // Method java/io/PrintStream.println:(I)V
      41: return
}

この時点で、ローカル変数テーブル0は、これは、1ローカル変数データPARAM 2であります

メンバ変数を直接使用例


public class ThisDemo {


    private List<String> data = new ArrayList<>();

    public void someMethod(String param) {

        if (data != null && data.size() > 0 && data.contains(param)) {
            System.out.println(data.indexOf(param));
        }

    }
}

コンパイラ:javacのThisDemo.java

分解:てjavap -c ThisDemo

public class com.imooc.basic.learn_source_code.local.ThisDemo {
  public com.imooc.basic.learn_source_code.local.ThisDemo();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: aload_0
       5: new           #2                  // class java/util/ArrayList
       8: dup
       9: invokespecial #3                  // Method java/util/ArrayList."<init>":()V
      12: putfield      #4                  // Field data:Ljava/util/List;
      15: return

  public void someMethod(java.lang.String);
    Code:
       0: aload_0
       1: getfield      #4                  // Field data:Ljava/util/List;
       4: ifnull        48
       7: aload_0
       8: getfield      #4                  // Field data:Ljava/util/List;
      11: invokeinterface #5,  1            // InterfaceMethod java/util/List.size:()I
      16: ifle          48
      19: aload_0
      20: getfield      #4                  // Field data:Ljava/util/List;
      23: aload_1
      24: invokeinterface #6,  2            // InterfaceMethod java/util/List.contains:(Ljava/lang/Object;)Z
      29: ifeq          48
      32: getstatic     #7                  // Field java/lang/System.out:Ljava/io/PrintStream;
      35: aload_0
      36: getfield      #4                  // Field data:Ljava/util/List;
      39: aload_1
      40: invokeinterface #8,  2            // InterfaceMethod java/util/List.indexOf:(Ljava/lang/Object;)I
      45: invokevirtual #9                  // Method java/io/PrintStream.println:(I)V
      48: return
}

この時点で、2つだけのローカル変数テーブル、すなわちこれとPARAM。

我々はまた、より詳細な情報を表示することができてjavap -c -v、この例のIDEAで使用されるスクリーンショットのプラグインのためにjclasslibバイトコードビューア、このブログツール上の別の記事で私の興味を参照してください:「IDEAを表示する学習バイトコードアーティファクトjclasslibバイトコードビューアプレゼンテーション。」

 

3.3分析

ソース内の事実によって、私たちはよく最適化され、最終的に理解されていません。

私たちは、コンパイルするには、2つのクラスをしており、解体はっきりと見ることができます。以上の行の最初のコード例はなく、逆コンパイル、バイトコードの後に短いです

それが最初の例よりも長い逆コンパイルバイトコードの後に​​第二の例?

私たちは、メインによりが見つかりました:のgetField#4 //フィールド、データ:Ljava / UTIL /リストを、  ここに

つまり、各データ取得オブジェクトが最初にaload_0その後、命令フェッチGETFIELDしなければなりません。

ローカル変数テーブルを維持することによりAstore_2最初の例では、直接aload_2各オペランドスタックにローカル変数テーブルから直接ロード。

これにより、必要性を排除することは、常にこのオブジェクトからプロパティを取得するため、より効率的。

 

ビットキャッシュ一般的に使用されるコードを書くようなこのアイデアは、データがキャッシュされ、優先チェックキャッシュの使用後にチェックするために、最近使用されようとしています。

自然の中で体現は、地域や時間的局所宇宙オペレーティングシステムの概念は、(次の本かは、Baiduのを断るかどうかを知りません)

そのため、専門知識とを接触させることによって、実際の開発経験を接触させることによって、バイトコードを解析することで、問題は、我々はそれを考え出しました

 

さらにまた、それは時間のためのスペースを使用してのアイデアを反映しています


のみ、それらを介しての知識、理解がより安全になることができます。

ここにも、プロの基礎の重要性を反映しています。

また知識がより深く理解するために、メモリは、より安全な柔軟に適用される可能性がより高いことができるためには、思考の性質にリンクすることができます。

IVの概要

これはあなたに別の視点を与えることができますJVMバイトコードを学ぶだけでは非常に典型的な例として、ある、あなたは学習の1つの以上の方法を確認します。

多くの人々は、彼らが勉強したいと言うかもしれませんが、起動することはできません、ここで見て、我々は他の強くお勧めします、通常より身近ゆっくり、てjavap命令をノック、「Java仮想マシン仕様」を組み合わせた後、「Java仮想マシンの深い理解」をお勧めしますとjclasslibバイトコードビューアプラグインあなたは指示部にジャンプする]をクリックすることができ、それは大きな助けを学ぶ、命令のJava仮想マシンの仕様を記述しています。

多くの人々は、これは学ぶことが遅すぎる、と言うかもしれません。

実際に、どのように特に良い学ぶことはとても不安になることができますか?細い太い髪へのプロットは、それは学ぶことができますどのように何かが失われると寂しいです。

本論文では、私たちが理解することができたの例では、JVMバイトコードは、Javaの構文の一部(ここでは、限られたスペースと、あまりにも多くの例が、与えられていない、興味のある学生は、自分でそれを試してみてください)、そしてあなたが学ぶにも助けを理解するのに役立ちますソース。

想像して、あなたはどのように問題を解決するために使用することができ、あなたが理解していない場合でも、役に立たないバイトコード学習と思いますか?

あなたが成長のために自分でより多くの機会を与え、快適ゾーンを破るためにあえてし、限界によって、あなたの成長の成長を支援するための知識を持っています。

-------------------

ようこそ親指アップ、コメント、転送、あなたの励ましは、私の仕事の原動力です。

 

 

公開された379元の記事 ウォンの賞賛862 ビュー132万+

おすすめ

転載: blog.csdn.net/w605283073/article/details/103247217