簡體   English   中英

實例化后,對象仍為Null

[英]Object is Null even after instantiating it

我對此代碼有疑問:

Object obj = null;
someMethod(obj);
System.out.println(obj.getId());
..
..
void someMethod(Object obj) {
    obj = new Object();
    obj.setId("Id1");
}

上面的代碼拋出NullPointerException 誰能告訴我為什么即使在方法中實例化該對象后,它為何仍然為空?

調用someMethod(obj)不能更改obj變量的值(因為Java是按值傳遞語言),因此調用后obj仍然為null ,並且System.out.println(obj.getId()); 拋出NullPointerException

一個可行的替代方案:

Object obj = someMethod();
System.out.println(obj.getId());
..
..
Object someMethod() {
    obj = new Object();
    obj.setId("Id1");
    return obj;
}

Java是按值傳遞的,您將引用傳遞給對象,而不是對象本身。 我認為了解這一點非常重要,因為這將使您了解Java的工作原理要好得多,因此,讓我們逐步進行代碼,看看為什么它不能按您期望的方式工作。

Object obj = null;
someMethod(obj);
void someMethod(Object obj) {

在這里, obj引用被復制(不是對象實例,而是對象的引用),然后傳遞給someMethod

obj = new Object();

在這里,您將覆蓋obj值,但在方法范圍內。 請注意,調用方( someMethod之外)中的obj引用未更改,因為它是一個副本。 方法完成后,該范圍中的obj引用將被丟棄,因為我們超出了范圍,而您又回到了調用者范圍。 在此范圍內, obj仍為null 從而

System.out.println(obj.getId());

顯然拋出NullPointerException

如果要從方法中獲取新引用,則可以將其返回並在調用方作用域中進行分配,例如:

Object someMethod() {
    obj = new Object();
    // Do stuff with obj
    return obj;
}
Object obj = someMethod();

在Java中,您將參數傳遞給方法時將其復制。 當我們談論對象時,您傳遞引用的副本。 因此,在您的方法內部分配對象-您正在將它們應用於引用的副本。

您需要包裝obj引用並在內部傳遞包裝器,而不是使用setter方法設置obj引用。

第二種解決方案是從方法中返回對象。

void someMethod(Object obj1) { // incoming obj1 with reference to obj
    obj1 = new Object();   // now when you do new Object() obj1 contains new reference
    obj1.setId("Id1"); // the object referred by the obj1 reference is updated 
}

基本上,java使用按值傳遞。 當您調用someMethod(obj) ,您只是將對obj的引用作為參數而不是對象本身進行傳遞。在someMethod ,將初始化對象變量,現在somemethodobj1現在包含對其他對象的引用對象(不是您從調用類發送的對象)。

因此,當您的程序返回到調用類時,那里的obj再次引用最初發送的原始引用,即指向null對象。 因此,您得到一個nullpointerexception 請注意,調用方法時,將為其分配自己的堆棧框架,因此,當調用返回時, somemethod()obj1和調用類的堆棧中的obj是不同的。

由於變量obj 未更改 ,因此您得到了NullPointerException 當調用方法someMethod並將obj傳遞給它時,則按不是按引用傳遞obj。

Java按值傳遞方法參數:它復制您作為參數提供的對象的副本,而不是對該方法進行引用; 對復制的對象(然后可以返回並使用)進行任何更改,而不是對實際對象進行任何更改。

Java通過值將對對象的引用傳遞給它。

這一點

someMethod(obj);

沒有創建對象,因此參考值為null。

如果您在somemethod()方法中更新引用變量並將其返回給obj變量,您將看到兩個引用都指向同一對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM