web-dev-qa-db-ja.com

java)でオブジェクトをfinalとして宣言する

誰かが以下のコードの重要性を明確にすることができますか?.

class A
{
    int i = 10;

    public void setI(int b)
    {
        i = b;
    }

    public int getI()
    {
        return i;
    }
}

class Test
{    
    public static void main(String args[]) throws Throwable
    { 
        final A ob = new A();
        ob.setI(10);
        System.out.println(ob.getI());
    }
}

オブジェクトAはfinalとして宣言されていますが、このオブジェクトのインスタンス変数の値を変更したり、更新された値を取得したりすることもできます。では、オブジェクトを最終として宣言することの重要性は何ですか。プリミティブデータ型をfinalとして宣言し、その変数を定数にすることを知っています。

17
RickDavis

obは他のオブジェクトを参照できなくなります: 最終キーワード

再割り当てすることはできません。ただし、その内部を変更することはできます(元々あった場合は変更可能です)。だからこれはうまくいく:

  final A ob = new A();
  ob.setI(6)

しかし、これはしません:

  final A ob = new A();
  ob = new A();
35
NimChimpsky

変数をfinalに指定すると、メモリに含まれている値を変更したくないことを意味します。プリミティブ型の場合、変数で表される値が実際の値です。オブジェクトタイプの場合、メモリ内の値はオブジェクトへの参照であり、実際のオブジェクトではありません。

たとえば、次のようになります。

final int x = 7;
final Object y = new Object();

データは次のようにメモリで表されていると考えることができます。

+----------+----------+
|  block   |  value   |
+----------+----------+
|  1001    |    7     |
|  1002    |  2110    |
+----------+----------+

議論のために、Javaが実際にメモリを管理する方法の詳細は省略しましょう(私もそれについてあまり知らないため)。したがって、上記の例では、ブロック1001が表されています。変数xによる、およびyによる1002。どちらも最終変数であるため、それらが表す値は変更できません。xの場合は実際の値である7ですが、yの場合は2110は単なる参照です。どちらも変更できませんが、プリミティブ型変数が定数になる理由は、実際の値を表すためです。しかし、実際には、オブジェクト型変数についても同じことが言えますが、定数それらが表すのは参照です。したがって、finalキーワードはこの点でほぼ一貫しています。

したがって、final変数では、プリミティブ型の場合、設定した特定の値を常に表します。それらがオブジェクト/参照型である場合、それらは(オブジェクトの可変性に関係なく)常にそれらを指すオブジェクトを指します。

12
Psycho Punch

これは、次のことが不可能であることを意味します。

final A ob = new A();
ob = new A(); // This is not possible

変数obは、最初に割り当てられたクラスAのインスタンスも参照します。これが、この場合のfinalキーワードの意味です。これは、obの他のインスタンスと同様に通常のオブジェクトであるため、Aの属性を変更できることを意味します。

4
Simeon Visser

オブジェクトがfinalの場合、通常どおり内部変更を行う任意のメソッドを呼び出すことができますが、別のオブジェクトを指すように参照を再割り当てすることはできません。これを試してください:

final A ob = new A();
ob = new A();

コードがコンパイルされないことに注意してください。

これを一定の参照と考えてください。

3
Tudor

さて、オブジェクトの場合、参照の値はオブジェクトへのアドレスです。したがって、obの値は、最終的なnew A();によって作成されたオブジェクトのアドレスになり、その値を変更することはできません。つまり、この参照に新しいオブジェクトを割り当てることはできません。

このように書くことはできません。

final A ob = new A();

ob= new A(); // not allowed
2
Ahmad

Javaには定数(最終)オブジェクトはありません。オブジェクトはヒープメモリ領域に作成されます。オブジェクトはいつでも変更できます。
Java :-)には定数(最終)参照のみがあります。つまり、参照は一定であり、全体を通して他のオブジェクトに再割り当てすることはできません。最終参照のは、宣言中に割り当てられている1つのオブジェクトのみを参照します。

したがって:

 final A objectA = new A();
 objectA.setI(6);  

参照ではなくオブジェクトのコンテンツのみを変更しているため、有効です。

だが:

   final A objectA = new A();
   objectA = new A();  

参照を変更しようとしているため、無効です。

1
Satya

Javaでは、C++とは対照的に、すべてのオブジェクトはポインターであるため、finalオブジェクトを変更できます。新しい場所を指すことはできません。つまり、オブジェクトを左側に配置することはできません。代入演算子。

1
Jakob Weisblat