繁体   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