10

私はnullJavaでどのように機能するかを理解しようとしています。

オブジェクトに割り当てるnullと、実際には舞台裏で何が起こりますか?「オブジェクト」などを指すメモリロケーションアドレスを割り当てnullますか?

私は次のプログラムを試しましたが、すべてnullが同じ場所を指していることがわかりました。

NullPointerExceptionしかし、Javaがどのようにスローされ、Javaでどのように機能するかを誰かに教えてもらえますnullか?

class Animal{
}

class Dog{
}


public class testItClass {

    public static void main(String args[]){
        Animal animal=null;
        Dog dog=null;

        if(((Object)dog) == ((Object)animal))
            System.out.println("Equal");
    }

}

出力

同等。

4

8 に答える 8

4

nullを任意のオブジェクトに割り当てると、実際にはヒープ内のメモリ位置またはその他の場所になります。

とを区別する必要がreferenceありobjectます。参照に割り当てることができnullます。オブジェクトは通常、new演算子を使用してヒープ内に作成されます。オブジェクトへの参照を返します。

A a = new A();

タイプを持つオブジェクトAはヒープ内に作成されます。参照が返されますa。今あなたが割り当てる場合

a = null;

オブジェクト自体はまだヒープ内にありますが、参照を使用してオブジェクトにアクセスすることはできませんa

オブジェクトは後でガベージコレクションされる可能性があることに注意してください。

UPD:

このクラスを作成して、そのバイトコードを確認しました(初めて):

public class NullTest {
    public static void main (String[] args) {
        Object o = new Object();
        o = null;
        o.notifyAll();
    }
}

そしてそれは以下を生み出します:

C:\Users\Nikolay\workspace\TestNull\bin>javap -c NullTest.class
Compiled from "NullTest.java"
public class NullTest {
  public NullTest();
    Code:
       0: aload_0
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: new           #3                  // class java/lang/Object
       3: dup
       4: invokespecial #8                  // Method java/lang/Object."<init>":()V
       7: astore_1
       8: aconst_null
       9: astore_1
      10: aload_1
      11: invokevirtual #16                 // Method java/lang/Object.notifyAll:()V
      14: return
}

参照結果にnullを設定していることがわかります。

8: aconst_null
9: astore_1

バイトコード命令のリスト

基本的に、nullの値をスタックの一番上に置き、参照に保存します。ただし、このメカニズムとリファレンス実装はJVMの内部にあります。

Javaオブジェクトへの参照はどのように実装されていますか?

于 2013-01-31T07:59:35.660 に答える
1

以下は、クラスのオブジェクトAnimal(またはそのサブクラス)への参照を宣言し、それを次のように初期化しますnull

Animal animal = null;

ここでは、参照自体がある程度のスペースを占めています。関連するオブジェクトがないため、それ以上のメモリコストは発生しません。

nullオブジェクトにアクセスして参照を使用しようとすると、次のようになります。

Animal cat = null;
if (cat.equals(dog)) { ... } // throws NPE

を取得しNullPointerExceptionます。

ただし、null参照を逆参照しようとしない限り、参照自体を操作することは問題ありません。

Animal cat = null;
Animal dog = null
if (cat == dog) { ... }      // works fine
于 2013-01-31T07:58:47.377 に答える
1

JavaのNullは、NULLオブジェクトパターンに基づいて設計されています。

NULLオブジェクトは、存在しないオブジェクトを意味します。この存在しないオブジェクトからリソースにアクセスしようとしても、何も取得しないはずです。これは論理的に意味があります。ただし、実際には、Javaなどのプログラミング言語はNullPointerExceptionクラスのインスタンスを作成し、必要な情報をオブジェクトに入力して、ステートメントの呼び出し時にスローします。

于 2013-09-17T09:42:19.017 に答える
0

Nullは、実際には何も参照しないメモリ参照です(したがってnull)。コード内のすべてのオブジェクト参照は、物理データが保持されているメモリ内の場所へのポインタです。オブジェクトがnullの場合、参照がないか、メモリ内の何も指していません。これが、nullがnullかどうかを確認する以外の目的でnullを使用できない理由です。

物理メモリ参照を持たないオブジェクトを操作しようとすると、Javaはnull例外をスローします。

于 2013-01-31T07:55:47.273 に答える
0

trueを出力するのはnull == null

ヌルは何も意味しません。

Animal animal=null;

オブジェクトへの参照を定義しAnimalますが、まだオブジェクトに割り当てられていないため、何も指していません。

C / C ++の経験がある場合は、NULLまたはにポインタを設定するようなものnullptrです。

于 2013-01-31T07:59:02.650 に答える
0

オブジェクトがnullthenに設定されている場合、基本的に、JVMにはメモリ参照がありません。また、==2つのnullオブジェクト間の比較でも真の値が得られます。

于 2013-01-31T08:02:06.023 に答える
0

nullJavaには1つしかありません。変数に関係なく、またクラスに関係なく、発生するすべての場合で同じです。コンパイラは直接比較することはできませんが、キャストすることはできます:

String x = null;
ArrayList a = null;
if ((Object) x == (Object) a) {
  System.out.println("Do not have onther nulls, only ME");
}
于 2013-01-31T08:06:33.467 に答える
0

バイトコードレベルでは、「null」をローカルスタックにプッシュする(そしてそれを可変スロットまたはフィールドに割り当てる)命令があります。

ほとんどのJava仮想マシンは、実際にはnullに割り当てられた実際の(マシン)ポインターを使用しています。したがって、それらが使用される場合、それらは内部で信号(SIGSEGV)をトラップし、それをNPEに変換します。「kill-SEGV」をJavaPIDに送信することで、これを実際にテストできます。ほとんどの場合、ランダムなNullPointerExceptionsが生成されます。

于 2014-07-25T23:57:51.343 に答える