Javaのnullとは何ですか?


252

なにnull

null何かのインスタンスはありますか?

どのセットがnull属していますか?

それはどのように記憶に表されますか?


yegor256。JLSからnullについて。「Nullリテラル。null型には、ASCII文字で構成されるnullリテラルnullによって表されるnull参照という1つの値があります。nullリテラルは常にnull型です。」記事中のポイントについて。「ミュータブルで不完全なオブジェクト」は機能です。「スローフェイル」は仕様による能力です。「コンピュータ思考対オブジェクト思考」は、2つの考え方にすぎません。「あいまいなセマンティック」は主観的すぎます。「アドホックエラー処理」は、エラーを処理するもう1つのタイプです。NullはリテラルまたはJLSで指定されたその他のものであり、良くも悪くもない。
Oleksii Kyslytsyn 2017

回答:


310

nullは何かのインスタンスですか?

いいえ、タイプが存在しないnullですがinstanceof

15.20.2型比較演算子 instanceof

RelationalExpression:
    RelationalExpression instanceof ReferenceType

実行時に、RelationalExpressionの値がそうでなく、参照をを発生させずにReferenceTypeにキャストできる場合、instanceof演算子の結果は次のとおりです。それ以外の場合の結果はです。truenullClassCastExceptionfalse

あらゆるタイプのことをこれは意味EしてR、いずれかのためにE oo == nullo instanceof R常にありますfalse


「null」はどのセットに属しますか?

JLS 4.1タイプと値の種類

名前のない特殊なnull型である式の型もありますnull。のでヌルタイプに名前がない、の変数を宣言することは不可能であるヌルに種類やキャストにヌルタイプを。null参照は、発現の唯一の可能な値であるヌルタイプ。nullこの基準電圧は常に任意の参照型にキャストすることができます。実際には、プログラマーはnull型を無視してnull、それを参照型にすることができる特殊なリテラルにすぎないふりをすることができます。


nullとは何ですか?

上記のJLSの引用が示すように、実際には、それは「単なる参照リテラルであり得る特別なリテラル」であると偽ることができます。

Javaではnull == null(これは他の言語では必ずしもそうではありません)。また、契約により、次の特別なプロパティ(からjava.lang.Object)もあることに注意してください。

public boolean equals(Object obj)

任意の非ためのnull基準値xx.equals(null)べきreturn false

これは、すべての参照タイプのデフォルト値(それらを含む変数の場合)でもあります

JLS 4.12.5変数の初期値

  • 各クラス変数、インスタンス変数、または配列コンポーネントは、作成時にデフォルト値で初期化されます。
    • すべての参照タイプのデフォルト値はnullです。

これの使い方はさまざまです。これを使用して、いわゆるフィールドの遅延初期化を有効にすることができます。フィールドは、null実際に使用されるまで初期値を保持し、「実際の」値(計算にコストがかかる可能性があります)に置き換えられます。

他の用途もあります。実際の例を見てみましょうjava.lang.System

public static Console console()

戻り値:システムコンソール(ある場合)、それ以外の場合null

これは非常に一般的な使用パターンですnull。オブジェクトが存在しないことを示すために使用されます。

ここでは別の使用例は、この時間からですjava.io.BufferedReader

public String readLine() throws IOException

戻り値String行の内容を含み、行終端文字を含まない、またはnullストリームの終わりに達した場合。

したがって、ここでreadLine()instanceof String、最終的にa nullが返されて終了を示すまで、各行で返されます。これにより、各行を次のように処理できます。

String line;
while ((line = reader.readLine()) != null) {
   process(line);
}

終了条件がに依存しないように、一つは、APIを設計することができreadLine()返しnullますが、一つは、このデザインは、物事を簡潔にすることの利点を持っていることがわかります。空の行なので、空の行には問題がないことに注意してください"" != null

今度は別の例を見てみましょうjava.util.Map<K,V>

V get(Object key)

指定されたキーがマップされている値、またはnullこのマップにキーのマッピングが含まれていない場合は、値を返します。

このマップがnull値を許可する場合、の戻り値はnull、マップがキーのマッピングを含まないことを必ずしも示すわけではありません。マップがキーをに明示的にマップすることも可能ですnull。このcontainsKey操作は、これら2つのケースを区別するために使用できます。

ここで、使用nullがどのように複雑になるかを確認し始めます。最初のステートメントは、キーがマップされていない場合nullは返されることを示しています。2番目のステートメントは、キーがマップされている場合でも返されるnull可能性があることを示しています。

対照的に、キーと値をjava.util.Hashtable許可しないことにより、物事をよりシンプルに保ちnullます。そのはV get(Object key)、が返された場合null、キーがマップされていないことを明確に意味します。

残りのAPIを読んで、どこでどのようnullに使用されているかを確認できます。これらは常にベストプラクティスの例ではないことに注意してください。

一般的に言えば、null以下を示す特別な値として使用されます。

  • 初期化されていない状態
  • 終了条件
  • 存在しないオブジェクト
  • 不明な値

それはどのように記憶に表されますか?

Javaで?心配はいりません。そして、それはそのようにしておくのが最善です。


あるnull良いこと?

これは今や主観的な境界線です。一部の人々は、nullそれが回避できたであろう多くのプログラマーエラーを引き起こすと言います。NullPointerExceptionJavaのようにキャッチする言語では、プログラマーのエラーですぐに失敗するので、Javaを使用するのが良いと言う人もいます。Nullオブジェクトパターンなどnullを使用して回避する人もいます

これはそれ自体が大きなトピックであるため、別の質問への回答として検討するのが最善です。

私はnull彼自身の発明者であるCAR Hoare(クイックソートの名声)からの引用でこれを終えます:

私はそれを10億ドルの間違いと呼んでいます。それはnull1965年の参照の発明でした。そのとき、私はオブジェクト指向言語(ALGOL W)での参照用の最初の包括的な型システムを設計していました。私の目標は、コンパイラーによって自動的に実行されるチェックを使用して、参照のすべての使用が完全に安全であることを確認することでした。しかしnull、実装が非常に簡単だったという理由だけで、参照を入れたいという誘惑に抵抗できませんでした。これにより、無数のエラー、脆弱性、システムクラッシュが発生し、過去40年間で10億ドルの苦痛と損害を引き起こした可能性があります。

このプレゼンテーションビデオはさらに深くなっています。お勧めの時計です。


4
ヌル参照NILは1960年にLISPに(として)存在し、おそらく以前にも存在していました。しかし、私はホーアがされないと思う本当にその引用符でヌル参照の請求発明にしようとしています。
スティーブンC

7
Hoareはnull参照の発明を主張しようとはしていません。彼は特に影響力のある場所でそれらを利用可能にしたと主張しているだけです。Javaを含め、Algolから明らかにインスピレーションを得た多くの言語があり、それらのnull参照の使用の一部がAlgolからインスピレーションを受けた、またはAlgolからコピーされた場合でも、Hoareはこれらのコストの一部の責任を負います。しかし、私は彼の推定はかなり低いと感じています。1兆ドルは本当のコストに近いかもしれません。
cjs 2013

32

nullは何かのインスタンスですか?

いいえ。そのため、すべてのクラスにnull instanceof X戻りfalseますX。(null型がオブジェクト型である変数に代入できるという事実に騙されないでください。厳密に言うと、代入には暗黙的な型変換が含まれます。以下を参照してください。)

「null」はどのセットに属しますか?

これはnull型の唯一のメンバーであり、null型は次のように定義されます。

「また、特別なnull型、つまり名前のない式nullの型があります。null型には名前がないため、null型の変数を宣言したり、null型にキャストしたりすることはできません。null参照は、null型の式の唯一の可能な値です。null参照は常に任意の参照型にキャストできます。実際には、プログラマーはnull型を無視して、nullは、参照タイプ。」 JLS 4.1

nullとは何ですか?

上記を参照。一部のコンテキストでnullは、「オブジェクトなし」、「不明」、または「使用不可」を示すために使用されますが、これらの意味はアプリケーション固有です。

それはどのように記憶に表されますか?

これは実装固有でありnull、純粋なJavaプログラムでの表現を見ることができません。(しかしnull、すべてではないにしてもほとんどのJava実装では、ゼロマシンアドレス/ポインタとして表されます。)


14

nullとは何ですか?

何もありません。

nullは何かのインスタンスですか?

いいえそれは何もないので、それは何かのインスタンスになることはできません。

nullはどのセットに属しますか?

セットなし

それはどのように記憶に表されますか?

いくつかの参照がそれを指す場合:

Object o=new Object();

ヒープメモリで、新しく作成されたオブジェクトに割り当てられたスペース。そしてoはメモリ内のその割り当てられたスペースを指し示します。

o=null;

これは、oがオブジェクトのそのメモリ空間を指さないことを意味します。


1
「現在、o = null。これは、oがオブジェクトのそのメモリ空間を指さないことを意味します。」これがJAVAでのガベージコレクションの動作方法だと思います
Hardik Mishra

9

いいえ、それは何かのインスタンスではありません。instanceofは常にfalseです。



6

Nullはどのクラスのインスタンスでもありません。

ただし、任意の(オブジェクトまたは配列)タイプの変数にnullを割り当てることができます。

 // this is false   
 boolean nope = (null instanceof String);

 // but you can still use it as a String
 String x = null;
 "abc".startsWith(null);

6

Java(tm)のnull

CおよびC ++では、「NULL」はヘッダーファイルで定義された定数で、次のような値が含まれます。

    0

または:

    0L

または:

    ((void*)0)

コンパイラとメモリモデルのオプションによって異なります。NULLは、厳密にはC / C ++自体の一部ではありません。

Java(tm)では、「null」はキーワードではなく、null型の特別なリテラルです。参照型にキャストできますが、intやbooleanなどのプリミティブ型にはキャストできません。nullリテラルの値は必ずしもゼロではありません。また、null型にキャストしたり、この型の変数を宣言したりすることはできません。


5

バイトコード表現

Java nullはJVMを直接サポートしています。それを実装するために3つの命令が使用されます。

  • aconst_null:たとえば、変数を次のnullように設定するObject o = null;
  • ifnulland ifnonnull:たとえば、オブジェクトを次のnullように比較するif (o == null)

第6章「Java仮想マシン命令セット」では、null他の命令への影響について説明NullPointerExceptionします。これらの命令の多くに対してがスローされます。

2.4。「参照タイプと値」null、一般的な用語でも言及しています。

参照値は、特別なnull参照、つまり、ここではnullで表されるオブジェクトなしへの参照でもかまいません。null参照には、最初は実行時の型がありませんが、任意の型にキャストできます。参照型のデフォルト値はnullです。


4

null特別な値であり、インスタンスではありません。明らかな理由で、それはinstanceof何にもなりません。


3

nullどのクラスのインスタンスでもない特別な値です。これは、次のプログラムで説明されています。

public class X {
   void f(Object o)
   { 
      System.out.println(o instanceof String);   // Output is "false"
   }
   public static void main(String[] args) {
      new X().f(null);
   }
}

6
この例が示す唯一のことnullは、のインスタンスではないということですString
Sasha Chedygov 2010

4
署名をvoid f(String o)に変更した場合、それはより理にかなっています。
Thilo

2

Javaのnullは、C ++のnullptrに似ています。

C ++のプログラム:

class Point
{
    private:
       int x;
       int y;
    public:
       Point(int ix, int iy)
       {
           x = ix;
           y = iy;
       }
       void print() { std::cout << '(' << x << ',' << y << ')'; }
};
int main()
{
    Point* p = new Point(3,5);
    if (p != nullptr)
    {
       p->print();
       p = nullptr;
    }
    else
    {
        std::cout << "p is null" << std::endl;
    }
    return 0;
}

Javaの同じプログラム:

public class Point {
    private int x;
    private int y;
    public Point(int ix, int iy) {
        x = ix;
        y = iy;
    }
    public void print() { System.out.print("(" + x + "," + y + ")"); }
}
class Program
{
    public static void main(String[] args) {
        Point p = new Point(3,5);
        if (p != null)
        {
            p.print();
            p = null;
        }
        else
        {
            System.out.println("p is null");
        }
    }
}

上記のコードから、Javaのnullが何であるかを理解できましたか?そうでない場合は、C / C ++でポインタを学ぶことをお勧めします。

CではC ++とは異なり、nullptrは未定義ですが、代わりにNULLが使用されます。これはC ++でも使用できますが、C ++ではnullptrの方がNULLだけよりも好ましいので、CのNULLは常にポインターに関連しているため、そのため、C ++では、単語の末尾に「ptr」というサフィックスが追加され、すべての文字も小文字になりましたが、これはそれほど重要ではありません。

Javaでは、非プリミティブ型のクラスのすべての変数は常にその型のオブジェクトまたは継承されたオブジェクトへの参照であり、nullはnullクラスオブジェクト参照ですが、nullポインターではありません。Javaにはそのようなものはなく、クラスへの参照です。オブジェクトが代わりに使用され、Javaのnullはクラスオブジェクト参照に関連しているため、「nullref」または「nullrefobj」と呼ぶこともできますが、これは長いため、単に「null」と呼びます。

C ++では、ポインタとnullptr値をオプションのメンバー/変数に使用できます。つまり、値を持たないメンバー/変数で、値がない場合はnullptrと等しくなるため、Javaでのnullの使用方法などです。


1

Javaの型には、プリミティブ参照の 2つの主要なカテゴリーがあります。プリミティブ型として宣言された変数は値を格納します。参照型として宣言された変数は、参照を格納します。

String x = null;

この場合、初期化ステートメントは変数「x」を宣言します。「x」は文字列参照を格納します。ここではヌルです。まず、nullは有効なオブジェクトインスタンスではないため、nullは割り当てられていません。これは、オブジェクト参照が現在オブジェクトを参照していないことを示す単なる値です。


0

私の意見では、Javaでnullを表示する興味深い方法は、情報がないことを示すものではなく、任意の型の参照に割り当てることができるリテラル値としてそれを表示することです。情報がないことを示していると考えると、a1 == a2がtrueであっても意味がありません(両方にnullの値が割り当てられている場合)。これらは実際に任意のオブジェクトを指している可能性があるためです(単にそれらが指しているべきオブジェクトがわからない)...ところで、Javaではnull == nullはtrueを返します。javaがSQL:1999のような場合、null == nullはunknownを返します(SQL:1999のブール値はtrue、false、unknownの3つの値を取ることができますが、実際にはunknownは実際のシステムではnullとして実装されます)... http://en.wikipedia.org/wiki/SQL


0

JLSからのすべての質問に正式に回答する短く正確な回答:

3.10.7。ヌルリテラル

null型には、ASCII文字で構成されるnullリテラルnullで表されるnull参照という1つの値があります。

nullリテラルは常にnull型です。

nullに割り当てられているタイプの参照のみが割り当てられます。参照には値(オブジェクト)を割り当てません。このような割り当ては、JVMに固有であり、参照がどの程度かかり、どのメモリ領域に割り当てられるかが決まります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.