ホームページ  >  記事  >  类库下载  >  JAVA構文の糖衣「+」演算子

JAVA構文の糖衣「+」演算子

高洛峰
高洛峰オリジナル
2016-10-15 09:50:201852ブラウズ

Iteger+String など、JAVA によって提供される「+」演算子は、C++ の観点から見ると、JAVA がこの「+」演算子をどのようにオーバーロードするのかを常に知りたいと思っていたので、String クラスに調べに行きましたが、手がかりがないので、JAVA がどのように実装しているのか気になります。JAVA が「+ 演算子のオーバーロード」をどのように実装するかを段階的に分析してみましょう。

public class Example {  
public static void main(String[] args) {  
Integer a = null;  
String b = a + "456";  
System.out.println(b);  
}  
}

このプログラムはとてもシンプルで、整数と文字列の「+」演算式です。実行結果: null456

サンプルプログラムを逆コンパイルします

コマンド:

javap -c Example

逆コンパイル結果は次のとおりです:

Compiled from "Example.java" 
public class com.boyu.budmw.test.Example extends java.lang.Object{ 
public com.boyu.budmw.test.Example(); 
  Code: 
   0:    aload_0 
   1:    invokespecial    #1; //Method java/lang/Object."<init>":()V 
   4:    return 
 
public static void main(java.lang.String[]); 
  Code: 
   0:    aconst_null 
   1:    astore_1 
   2:    new    #2; //class java/lang/StringBuilder 
   5:    dup 
   6:    invokespecial    #3; //Method java/lang/StringBuilder."<init>":()V 
   9:    aload_1 
   10:    invokevirtual    #4; //Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder; 
   13:    ldc    #5; //String 456 
   15:    invokevirtual    #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 
   18:    invokevirtual    #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 
   21:    astore_2 
   22:    getstatic    #8; //Field java/lang/System.out:Ljava/io/PrintStream; 
   25:    aload_2 
   26:    invokevirtual    #9; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 
   29:    return 
 
}

main関数部分を分析しましょう:

0: 定数nullをオペランドスタックにプッシュします

1 :オペランド スタックから null をポップし、インデックス 1 のローカル変数 a に保存します

2: new a StringBuilder

5: new によって以前に作成されたスペースをコピーし、オペランド スタックにプッシュします

6: 初期化の呼び出しが進行中です

9: 結果をオペランドスタックに保存します

10: StringBuilder.append(java/lang/Object)を呼び出します

13: "456"をスタックの先頭にプッシュします

15: StringBuilder.append(java/lang /String)

18: toString 関数を実行します

上記の分析から、最終的に最初に StringBuilder オブジェクトを生成し、後続の "+" 演算子はすべて StringBuilder.append() の "+" を呼び出していることがわかります。これは、オブジェクトを追加するときにオブジェクトを String に変換するために

public static String valueOf(Object obj) {  
return (obj == null) ? "null" : obj.toString();  
}

が呼び出される理由として、上記のサンプル プログラムが実行後に null456 になる理由を説明できます。

なぜ JAVA は演算子のオーバーロードをサポートしないのですか?

C++ と同様に、クラスは演算子のオーバーロードを制限するための標準がないため、個人的には難しい問題になると思います。確かに、オーバーロードによってセマンティックな違いが発生し、可読性が大幅に低下するため、Java で演算子のオーバーロードを削除する機能は、その高度なオブジェクト指向の性質と非常に一致しています。したがって、この問題については深く考えないでください。

追記

これらは開発プロセスでよく使用されるものですが、通常の開発プロセスではそれほど深く掘ることはなく、当然のこととして認識されます。発見されないケース。


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。