Java null object [duplicate] - java

This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 8 years ago.
So as far as I know, in java you can't access objects directly, you only have the pointer to it. So for example I have this code:
public class App {
public App() {
Thing t = null;
doStuff(t);
System.out.println(t);
}
public void doStuff(Thing a) {
a = new Thing();
}
public static void main(String[] args) {
new App();
}
}
class Thing { }
And the output is null. Why? I've passed the pointer to a method which gave it a new Thing instance to point to. Is it because it's a new pointer? Also how can I resolve it without returning anything from doStuff()?

You have references not pointers, and a method cannot update the callers reference without an assignment in the caller - so this
public App() {
Thing t = null;
doStuff(t);
System.out.println(t);
}
public void doStuff(Thing a) {
a = new Thing();
}
Would work if you did,
public App() {
Thing t = null;
t = doStuff(t);
System.out.println(t);
}
public Thing doStuff(Thing a) {
a = new Thing();
return a;
}

This is because Java works by pass by value of Object references and not pass by reference of an Object ,even if the reference is an Object,it still gets passed by the value of reference.So you always work with new references

Refer:http://docs.oracle.com/javase/tutorial/java/javaOO/objectcreation.html
Declaring a Variable to Refer to an Object
Previously, you learned that to declare a variable, you write:
type name; This notifies the compiler that you will use name to refer
to data whose type is type. With a primitive variable, this
declaration also reserves the proper amount of memory for the
variable.
You can also declare a reference variable on its own line. For
example:
Point originOne; If you declare originOne like this, its value will be
undetermined until an object is actually created and assigned to it.
Simply declaring a reference variable does not create an object. For
that, you need to use the new operator, as described in the next
section. You must assign an object to originOne before you use it in
your code. Otherwise, you will get a compiler error.
A variable in this state, which currently references no object, can be
illustrated as follows (the variable name, originOne, plus a reference
pointing to nothing):

Related

Understanding the concept of Java being pass by value? [duplicate]

This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 7 years ago.
One of the most popular answers to one of the most popular questions in Java here reads:
Java is always pass-by-value. The difficult thing to understand is that Java passes objects as references and those references are passed by value.
So what does "Java passes objects as references and those references are passed by value." mean?
Does it mean that:
The memory location to which the original variable points is copied as the value of the new temporary variable? (if this is the case, all the changes made inside the function will be reflected in the original, right?)
If not, what does it mean?
Think of objects references as "pointers to a value"
When you pass a value into a method, you pass the pointer in, therefore the two pointers (the one in the method, and the one you passed in) point to the same thing.
Consider this
public static void main(String[] args){
Foo cl = new Foo();
cl.z= 100;
method(cl);
System.out.println(cl.z);
}
private static void method(Foo bar){
bar.z=10;
}
Before you call method, cl.z would be 100, but after you pass it in, it would be equal to 10.
What is not correct is this:
public static void main(String[] args){
Foo cl = new Foo();
cl.z= 100;
method(cl);
System.out.println(cl.z);
}
private static void method(Foo bar){
bar = new Foo();
bar.z=10000;
}
This would NOT print out 10000, because you cannot assign the pointer to reference a different object
When we say Java is pass-by-value, it means that if you modify a parameter inside a method, it has no effect on the caller. For example:
public void swap(int a, int b) {
int temp = a;
a = b;
b = temp;
}
All this does is swap local copies of the parameters. Thus, if you say
int x = something;
int y = somethingElse;
swap(x, y);
x and y would not change.
The same is true for references:
public void someOperation(MyClass a) {
a = ...something...;
}
Inside your method, a is a copy of whatever reference you pass in; if you reassign a to something else in the method, it doesn't affect any variable in the caller.
MyClass x = ...;
someOperation(x);
x does not change, even though you've changed the parameter a inside the method.
Note that this means that x itself will not change. It will not point to a different MyClass instance, even though a in the method was changed to refer to a different MyClass instance. However, even though the reference does not changed, the object that the reference refers to could be changed by the method.
It means the reference (a memory pointer to the object) is passed by value. If you modify the object, you modify the reference to the object; thus the change will be seen across your application. If you modify the pointer, then your only change it for the scope of your method.
void method(Foo f) {
f.bar = 10; // Seen accross your application.
f = new Foo(); // Modifying your pointer. This does not change the previous object.
}
Yes, Java is always pass-by-value, with both reference types and primitive types. But that doesn't mean that changes within functions always affect the object passed in as an argument.
If a primitive type is passed in, then there is no reference passed, it's by pure value, and any values in the calling scope will not change.
If a reference type is passed in, whether or not a function can modify it depends upon if the type is mutable (the object can be modified) or immutable (the object itself cannot be modified, a new object must be created for all modifications).
If it is mutable, like StringBuilder or HashMap<String, String>, then the function is able to modify it and changes within the function will still be in place after the function call returns. However, note that changing what a reference type points to is not modifying it, in that case, you are only changing what the reference type points to, not the original object referenced by an argument, but doing an operation like strbuilder.append("xyz") is.
If it is immutable, like String or Integer then all modifications within the function will create a new object and the changes will not be in place after the function call returns.

Confusion in passing an object to a function [duplicate]

This question already has answers here:
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed 8 years ago.
while learning C language I have learned that when you pass a variable to a function. you are not passing the variable itself you are passing a copy of it so the actual varible's value will not change unless the function returns a value and you assign that value to the variable.
but I just executed this program and this happened when I passed "Newobj" object to a "changer" function and then change the values of the variables and then print the new variables values it is working. It should not happen right? because I am sending the copy of "Newobj" to "copyobj". explain please I am confused.
Note: Explain in detail please. My brain is slow. I know the concepts of c and few concepts of c++;
here is my code:
public class PassObjects {
int regno;
String name;
double per;
PassObjects(int a,String s,double p){
regno=a;
name=s;
per=p;
}
PassObjects changer (PassObjects copyobj){
copyobj.regno=797;
copyobj.name="Srimanth";
copyobj.per=70.9;
return copyobj;
}
public static void main(String[] args){
PassObjects Newobj= new PassObjects(86,"srimanth",85.4);
System.out.println("The original values of Instance variables are "+Newobj.regno+" "+Newobj.name+" "+Newobj.per);
Newobj.changer(Newobj);
System.out.println("The changeed values of Newobj are "+Newobj.regno+" "+Newobj.name+" "+Newobj.per);
}
}
output is here:
The original values of Instance variables are 86 srimanth 85.4
The changeed values of Newobj are 797 Srimanth 70.9
What you are doing is passing a pointer to an object. You are effectively modifying the PassObjects object.
There is a difference between a reference type and a value type. For example, a function that takes an integer and modifies it will indeed receive a copy of that integer.
public void add(int x)
{
x = x + 1;
}
However, an array of ints is also a reference type.
When you call this function using the following code:
int x = 5;
add(x);
// X will still have a value of 5.
This is because x is a value-type. You call the function and pass in a copy of the integer.
However, when you create an object, you do not pass a copy of the entire object. See code below.
public void ChangeName(SomeObject x, String newname)
{
x.name = newname;
}
SomeObject x = new SomeObject("thename");
ChangeNameTo(x, "newname"); // As the comment below pointed out, you don't even have to reassign.
//x.name will have the value "newname" now.
You can read more here and here.
Java does manipulate objects by reference, and all object variables are references.
That means u only created a new reference to the same object and when u changed the values then it gets changed in actual object.

Java shallow and deep copying JLS [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Java pass by reference issue
In my codes below, methodA will be called, which then delegates a call to methodB, in doing so, methodB assigns the input parameter with String literal "bbb", however, back at methodA, the string literal was not there, which section of the JLS defines this behavior?
package sg.java.test2;
public class TestApple {
public static void main(String args[]){
methodA();
}
public static void methodA(){
String a = null;
methodB(a);
System.out.println(a);
}
public static void methodB(String a){
a = new String("bbb");
}
}
this is a pass by value vs pass by reference issue. Java is pass by value ONLY. When you call
methodB(a)
the reference a gets copied; in the context of methodB, a is a different variable that has the same value as in methodA. So when you change it in methodB, a in methodA still points to the original String.
Another issue that comes into play here is that Strings are immutable, so you can't change the value of a String once it is set. From the docs.
Strings are constant; their values cannot be changed after they are
created.
What you could do is
a = methodB();
and return "bbb" in methodB. There is no reason to pass a in because you are not operating on it; I think you were only doing it to try to change a in the context that calls methodB, which you cannot do.
Finally, the relevant part of the JLS is 8.4.1, which says
When the method or constructor is invoked (ยง15.12), the values of the
actual argument expressions initialize newly created parameter
variables, each of the declared Type, before execution of the body of
the method or constructor. The Identifier that appears in the
DeclaratorId may be used as a simple name in the body of the method or
constructor to refer to the formal parameter.
Java is pass by value, not pass by reference.
The method signature is shorthand for this:
methodB() {
String a = arguments[0];
i.e. it is a difference reference. When you assign to 'a', you are assigning to the reference 'a' created as part of the method signature, not to the 'a' you declared in the code block that contained the call to methodB().
You can modify the value if it is an object, however.
class MyObj {
String prop;
public MyObj(String s) { prop = s; }
public MyObj() { }
}
public void methodB(MyObj o) {
o.prop = "foo";
}
public void methodA() {
MyObj a = new MyObj();
System.out.println(a.prop); // null
methodB(a);
System.out.println(a.prop); // foo
}

Java - This seems like pass by reference to me [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Is Java pass by reference?
So consider the following two examples and their respective output:
public class LooksLikePassByValue {
public static void main(String[] args) {
Integer num = 1;
change(num);
System.out.println(num);
}
public static void change(Integer num)
{
num = 2;
}
}
Output:
1
public class LooksLikePassByReference {
public static void main(String[] args) {
Properties properties = new Properties();
properties.setProperty("url", "www.google.com");
change(properties);
System.out.println(properties.getProperty("url"));
}
public static void change(Properties properties2)
{
properties2.setProperty("url", "www.yahoo.com");
}
}
Output:
www.yahoo.com
Why would this be www.yahoo.com? This doesn't look like passbyvalue to me.
The reference is passed by value. But the new reference is still pointing to the same original object. So you modify it. In your first example with the Integer you are changing the object to which the reference points. So the original one is not modified.
Your first example does:
num = 2
That is the same as
num = new Integer(2)
So you see how it is not quite the same as your second example. If Integer let you set the value in it, you could have done:
num.setValue(2) // I know Integer doesn't allow this, but imagine it did.
which would have done exactly what the second example did.
This is pass-by-value, but the value is the reference to properties, and you don't change it, only some inner field of it.
In the first case you change the reference, not any member of the reference, while in the second you change a member of the reference, but leave the reference as is.
Try this:
public class LooksLikePassByReference {
public static void main(String[] args) {
Properties properties = new Properties();
properties.setProperty("url", "www.google.com");
change(properties);
System.out.println(properties.getProperty("url"));
}
public static void change(Properties properties2)
{
properties2 = new Properties();
properties2.setProperty("url", "www.yahoo.com");
}
}
It prints out "www.google.com".
You are actually passing the value of the reference, so changes made to the object via that reference will be seen. If you assign a new object reference to the parameter, though, that change will not be reflected, since you've only passed the value of the reference, rather than an actual reference to a variable.
That's because properties2 is nothing more than an object reference. This means the references passed to the method are actually copies of the original references. As this illustrates,

How to use references in Java?

I want to use reference in Java but I don't know how!
for example in C++ we write:
void sum(int& x)
{
...
}
but in Java & sign is a compiler error!
please help me to understand references in Java.
Objects are passed by reference by default Objects are accessed by reference, but there is no way to create a reference to a primitive value (byte, short,int, long). You either have to create an object to wrap the integer or use a single element array.
public void sum(int[] i){
i[0] = ...;
}
or
public void sum(MyInt i){
i.value = ...;
}
public class MyInt{
public int value;
}
for your example something like the following could work
public int sum(int v){
return ...;
}
or
public int sum(){
return ...;
}
Update:
Additional/Better description of object references:
Java Objects are always accessed by a reference. Like the primitive types this reference is passed by value (e.g. copied). Since everything a programmer can access in java is passed by copying it (references, primitives) and there is no way to create a reference to a primitive type, any modification to a method parameter (references, primitives) only affects the local copy within the method.
Objects can be modified within a method since both copies of the reference (local and other) still point to the same object instance.
example:
Modify a primitive within method, this only affects the internal copy of i and not the passed value.
void primitive(int i){
i = 0;
}
Modify a reference within method, this only affects the internal copy of ref and not the passed value.
void reference(Object ref){
ref = new Object();//points to new Object() only within this method
}
Modify an object, visible globally
void object(List l){
l.add(new Object());//modifies the object instead of the reference
}
Both the array and MyInt above are based on the modification of an object.
An ordinary Java parameter already is closer to a C++ reference than to C++ pass-by-value or pass-by-pointer. So, all your Java methods are already like this.
int and other primitives are special in Java, however; the above is true for object references.
Edit: More precisely, as stated #fatih, all Java invocations are pass-by-value. However, when you pass an object you are passing a reference by value. So, as a first approximation, the above statement is correct: An ordinary Java parameter is more similar to a C++ reference than to C++ pass-by-value or pass-by-pointer.
Required reading on understanding Java's Pass By Value semantics:
http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html
http://javadude.com/articles/passbyvalue.htm
http://javachannel.net/wiki/pmwiki.php/FAQ/PassingVariables (links to several other pages)
Completely remove the notion from your head that Java can have anything passed by reference. Let's look at an example, shall we?
public class App
{
public static void main( String[] args )
{
Foo f1 = new Foo();
doSomethingToFoo(f1);
System.out.println(f1.bar); //Hey guess what, f1.bar is still 0 because JAVA IS PASS BY VALUE!!!
}
static void doSomethingToFoo(Foo f) {
f = new Foo();
f.bar = 99;
}
static class Foo {
int bar = 0;
}
}
The MutableInt class in Apache Commons will do what you want, although it's not pretty.
MutableInt
void sum(MutableInt mx)
{
int x = mx.getValue();
x = ...
mx.setValue(x);
}
...
MutableInt mx = new MutableInt(5);
sum(mx);
int result = mx.getValue();
Additional classes are provided for other primitive types, and also for objects.
There is some overhead involved in creating an additional object simply to provide a reference, so the solution is not optimal, but in most cases you should be ok.
In general, it is always best to find a way to return a result from a method. Unfortunately, Java only allows one value to be returned in this way.

Categories