简体   繁体   English

实例化后,对象仍为Null

[英]Object is Null even after instantiating it

I have a question regarding this code: 我对此代码有疑问:

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

The above code is throwing NullPointerException . 上面的代码抛出NullPointerException Can anyone tell me why is the object still null even after instantiating it inside the method? 谁能告诉我为什么即使在方法中实例化该对象后,它为何仍然为空?

The call someMethod(obj) can't change the value of the obj variable (since Java is a pass by value language), so obj is still null after the call, and System.out.println(obj.getId()); 调用someMethod(obj)不能更改obj变量的值(因为Java是按值传递语言),因此调用后obj仍然为null ,并且System.out.println(obj.getId()); throws NullPointerException . 抛出NullPointerException

An alternative that would work : 一个可行的替代方案:

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

Java is pass by value, and you pass the reference to an object, not the object itself. Java是按值传递的,您将引用传递给对象,而不是对象本身。 I think it is very important to know this since this will let you understand how Java works much much better, so let's go step by step on your code and see why it doesn't work the way you expect. 我认为了解这一点非常重要,因为这将使您了解Java的工作原理要好得多,因此,让我们逐步进行代码,看看为什么它不能按您期望的方式工作。

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

Here, obj reference is copied (not the object instance, only the reference to it) then passed to someMethod . 在这里, obj引用被复制(不是对象实例,而是对象的引用),然后传递给someMethod

obj = new Object();

Here you're overwriting obj value but only in the scope of the method. 在这里,您将覆盖obj值,但在方法范围内。 Note that obj reference in the caller (outside someMethod ) has not changed, because it is a copy. 请注意,调用方( someMethod之外)中的obj引用未更改,因为它是一个副本。 After the method finishes, obj reference in this scope is discarded because we go out of scope, and you go back to the caller scope. 方法完成后,该范围中的obj引用将被丢弃,因为我们超出了范围,而您又回到了调用者范围。 In this scope, obj is still null . 在此范围内, obj仍为null Thus 从而

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

obviously throws NullPointerException . 显然抛出NullPointerException

If you want to get the new reference from the method, you can return it and assign it in the caller scope, for example: 如果要从方法中获取新引用,则可以将其返回并在调用方作用域中进行分配,例如:

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

In Java you copy arguments when passing them to a method. 在Java中,您将参数传递给方法时将其复制。 When we are talking about objects, you pass copy of reference. 当我们谈论对象时,您传递引用的副本。 So assigning object inside of your method -you are applying them to the copy of reference. 因此,在您的方法内部分配对象-您正在将它们应用于引用的副本。

You need to wrap obj reference and pass wrapper inside, than use setter method to set obj reference. 您需要包装obj引用并在内部传递包装器,而不是使用setter方法设置obj引用。

Second solution would be to return you object from your method. 第二种解决方案是从方法中返回对象。

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 
}

Basically java uses pass by value. 基本上,java使用按值传递。 When you call the someMethod(obj) , you are just passing the reference to the obj as an argument and not the object itself.When inside the someMethod , the object variable is initialized and now the obj1 inside the somemethod now contains reference to some other object(not the one you sent from the calling class). 当您调用someMethod(obj) ,您只是将对obj的引用作为参数而不是对象本身进行传递。在someMethod ,将初始化对象变量,现在somemethodobj1现在包含对其他对象的引用对象(不是您从调用类发送的对象)。

So when your program returns to the calling class, the obj there again refers to the original reference that was sent initially ie to a null object. 因此,当您的程序返回到调用类时,那里的obj再次引用最初发送的原始引用,即指向null对象。 Hence you get a nullpointerexception . 因此,您得到一个nullpointerexception Note that when a method is invoked, it gets allocated its own stack frame, hence the obj1 inside somemethod() and obj inside the calling class' stack are different when the call returns back. 请注意,调用方法时,将为其分配自己的堆栈框架,因此,当调用返回时, somemethod()obj1和调用类的堆栈中的obj是不同的。

You get a NullPointerException due to the fact that the value of the variable obj has not changed . 由于变量obj 未更改 ,因此您得到了NullPointerException When you call the method someMethod and pass obj to it, then you passed obj by value and not by reference . 当调用方法someMethod并将obj传递给它时,则按不是按引用传递obj。

Java passes method arguments by value: it makes a copy of the object that you gave as an argument as opposed to giving a reference to it to the method; Java按值传递方法参数:它复制您作为参数提供的对象的副本,而不是对该方法进行引用; any changes are made to the copied object (that you can then return and use), not to the actual object. 对复制的对象(然后可以返回并使用)进行任何更改,而不是对实际对象进行任何更改。

Java passes by value the reference to an object. Java通过值将对对象的引用传递给它。

At this point 这一点

someMethod(obj);

no object was created so the reference value is null. 没有创建对象,因此参考值为null。

If you update the reference variable inside the method somemethod() and return it to the obj variable you will see that then both references point to the same object. 如果您在somemethod()方法中更新引用变量并将其返回给obj变量,您将看到两个引用都指向同一对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM