JAVA class null value - java

I would like to ask if there is anyways in java to ensure that a class can never be instantiated as null. But i want to do this inside the class. For example
class A
{
I can never be null
}
class B
{
A a = null ; << No you cant. Does not compute :P
}
Thanks in advance.

This is not, generally speaking, possible. When you declare:
A a = null;
A a2 = new A();
Both a and a2 are references, not actual objects. Think of a reference as a pointer, but one that does not support C-style pointer arithmetic.
A a = null;
sets up a reference (a pointer) that can point to an object of type A, but is currently initialized to null. It's not possible to have class A ensure that there are never any null references to things of type A.

No.

No. You cannot do that. What is your use case, maybe we can suggest an alternative.

We often talk about a null object but that is totally misleading. An object is an object and only a variable can hold the value null (instead of a reference to an object).
Something like a null object simply doesn't exist in Java.
If we do a
A a = new A();
we create a new instance of A and store a reference (a pointer) to this instance at the variable. The variables value is now some sort of address of the location of this new object. If the instantiation fails (an exception is thrown) then no assignement will be made and the variable keeps its old value. Which may be null - but again, this just tells us that the variable doesn't hold a reference to any object.

Related

How to properly copy objects [duplicate]

This question already has answers here:
How do I copy an object in Java?
(23 answers)
Closed 8 years ago.
This might have been asked already but since I am not so sure how to phrase it I could not find it.
Essentially
Suppose we have the class a, (see code below), and we want to copy an instance of it, a1, to another instance a2.
So, in my main I would have a1.copy(a2)
I know that using copy2 method this will work. However copy1 will not. I just would like to clarify why this is. Is it because the parameter is just a "copy" of the object, so the object itself (a2) is not altered.
class a {
private int val;
public class(int val){
this.val = val;
}
public void copy1(a obj){
obj = this;
}
public void copy2(a obj) {
obj.val = this.val;
}
}
The key to understand your problem is that Java's method call is always pass-by-value, not by reference.
When you call a.copy1(b), Java copies a value of b's reference(say it is called b_copy, please note that b_copy points to the same memory location as b), and then pass b_copy to the method copy1.
And in your method of copy1, Java only changes the reference of b_copy.
public void copy1(b_copy){
b_copy=a;
}
So now :
b_copy: b_copy=a;
b: b does not change at all;
When the method ends,b_copy dies. So nothing changes on b!
While a.copy2(b) manipulates on the object itself, but it still copies a new value of b(say b_copy again) and pass into copy2
public void copy2(b_copy){
b_copy.val = a.val;
}
Since b_copy points to the same memory of b, so when you do changes on b_copy.val, you also does the same on b.val itself. That's the reason why b changes.
So now :
b_copy: b_copy, but b_copy's val changes
b: b's val also changes, since b_copy is points to the b's memory location;
And then when method ends, b_copy dies, and b has changed!
You may find more discussion on Is Java "pass-by-reference" or "pass-by-value"?
And you may also need How do I copy an object in Java?
When you call the method copy1(), the parameter is a copy of the reference of the object a obj. When you set it to this (obj = this;) the copy of the reference of the object is replaced by the current object, but the original object and the reference to the object at the place you are calling the copy1() method stays the same. You just change the copy of the reference of the object.
When you call the method copy2(), no reference work is done there, and you are doing one by one matching of the variables (properties of the objects) and there is no copy of reference work there. You are changing the object itself. In this case, this.val = obj.val; would also work.
For more understanding, check this topic and check how other languages like C or C++ handle parameter passing issue.
I think you might want to look into how parameters are passed in Java.
For primitive variables, they are passed by value. If I recall correctly, this means that a temporary value is passed and any changes to the variable in the function update only the temporary variable.
However, objects are passed by reference. This means that instead of the entire object, essentially a pointer to where the object is in memory is passed.
What this means is that updating an object's variables produces lasting effects on that object. Additionally, if you set one object equal to another object, you're really just setting the memory references to be the same (a byproduct of this is that the values of the variables in the objects are then linked).
This explains why the first function fails to do what you want (you're setting the memory locations to be the same). And the second succeeds (you're performing a deep copy into a new memory address).
Your reasoning is correct. When you pass an object to a method (as you do in copy1), all you are doing is creating another reference to the same object. If you override this reference, as copy1 does, it just means that that reference now points to a different object - it does not, and can not, change the original object.

what exactly happen in jvm when i create an object in java?

To my understanding if i am writing
Car a3=new Car()
This statement will create a handle named a3 in jvm stack with all its properties in JVM heap.
IF this is correct i am wondering how call by value works.
So, if i create a method checkMethod(Car c) and call it by saying checkMethod(a3);
suppose our car is
public class Car{
int a=0;
public int getpar(){
return a;
}
}
in checkMethod i try to access a using a3.a = 5; so i changed the value of a3.a
it will show me in the calling class as well as it was pointing to the same fields that jvm created in the heap.
But when i do a3= null; in the calling method and go back again in the method from which i was calling
checkMethod(a3) and try to see this object it is not null?
Why it behaved differently as compared to property of object that is a???
checkMethod(a3);
Pass a copy of a value which is a reference to object instance of Car
Inside method...
a3.a = 5
Using a3, modify object instance of Car which is identified by a3 ( which is a copy of original a3).
a3 = null
Set the reference to null ( copy)
When this happens, only the copy you passed to your method will point to null. But the original a3 still points to your object instance of Car.
Why it behaved differently as compared to property of object that is a?
Because Java is (pure) call by value. You cannot manipulate the value of the parameter within the callee context. You always gets a local copy in the calling context.
On method calls, Java passes a copy of the reference.
So when setting a3 to null, it only set its copy of the reference to null and the other copies that are stored else where.
The whole trick is this: Java passes references by value :)

Overload a C++ assignment operator to behave like Java

In Java, when you assign one object to another, the original object isn't copied, it merely clones the reference. So, for example, I'd like it to behave like this Java code:
SomeClass x = new SomeClass();
SomeClass y;
y = x; // x is not copied, y is simply a (Java) reference to x
What I'd like to do is create a C++ class that behaves the same way. The obvious choice is to overload the assignment operator, like so:
SomeClass& operator=(const SomeClass& rhs)
{
this = &rhs;
return *this;
}
Unfortunately, assigning a new location to this is not allowed; the above code won't even compile.
Does anyone know of any other way to do this?
Also, before you say anything: yes, I know this is absolutely the wrong way to implement an assignment operator. Please, indulge me anyway.
EDIT 2: To clarify, here is the C++ code that should behave as in Java:
SomeClass x = SomeClass(); // Created on stack
SomeClass y; // In C++, same as above; NOT reference or pointer
y = x; // x is not copied, y becomes a (C++) reference to x;
// original y is destroyed when stack unwinds
I DO NOT want to use pointers at all.
EDIT: I'm doing this to see if I can change the base address of a C++ object that was passed by reference to a function. If I simply assign another object to the reference variable, it automatically makes a shallow copy, and I don't want that. I want the reference parameter to reference a completely different object.
I'm doing this to see how references are implemented by the compiler. If references are syntactic sugar for dereferenced pointers, then outside the function, the base address of the argument object would NOT change. If they are aliases in the symbol table (as in PHP), then it WILL change. (So any solution using pointers is out, since that's my "control" for the test.)
Hope that makes sense.
This isn't possible. The languages just work fundamentally differently.
SomeClass x in Java is some kind of pointer or reference to a SomeClass object. It's an indirection, so that why you can have multiple ones refering to the same object.
SomeClass x in C++ literally is the object. Thus SomeClass y is literally an entirely different object. There's no indirection. And so there's no way to make one reference the other.
C++ provides pointers (SomeClass* x) and references (SomeClass& x) to take care of the times when indirection is needed. Perhaps those are what you actually want to use, although it depends on why you asked this question in the first place.
Responding to the edit:
No, you can't change the address of an object. An instance of an object will live in exactly one place for the duration of its lifetime, until it is destroyed/deallocated.
I don't think this is okay, because even you assign this to another pointer, then the current object pointed by this will be memory leaked. Java has memory collection, but C++ not.
This is a good question, through. And this is possible.
A& operator=(const A& rhs)
{
A * cthis = const_cast<A*>(this);
cthis = const_cast<A*>(&rhs);
return *cthis;
}
Edit: It is possible to change "this pointer" inside a member function. But changing "this pointer" doesn't accomplish much.
It can be done. but, with pointer indirection.
Lets say you have a class someClass
class someClass
{
someClass *someClsPtr;
public:
someClass(someClass *someClsPtrTemp):someClsPtr(someClsPtrTemp)
{
}
someClass* operator=(someClass *someClsPtrTemp)
{
this->someClsPtr = someClsPtrTemp->someClsPtr;
return this;
}
//now over load operator -> and operator *. Thats it.
};

Is null a non-declared variable?

If I declare a class attribute like this:
private static String month;
I don't know if later in the code is right to check like this:
if(month == null){
month = "January";
}
My main question is, is null a non-declared variable?
What is the best approach to this?
Thank you in advance.
null is a built-in special constant that represents an empty object reference, not a variable. When you declare a variable representing an object at the class or at the instance level, its initial value is set to null. When you declare a local variable, you must set its value explicitly - to null or to some object.
Yes it is ok since all instance references are initialized to null.
But be careful, it is only true for instance references. The local ones must ALWAYS be initialized manually.
Best approach is always initialize your variable because if you dont then java will set it to null. Null means not referencing to any object which implies either not initialized or deliberately set as null
a null variable is a reference which doesn't point to an instantiated object. SO you have a reference to a string which is yet to be pointed to a string.
Class member variables are initialised with nulls for object references. Inside a method they aren't, so you'll need to initialise it before you use it in order to make it compile in those situations.
For objects null is the default value. In this case, month is String type, and String is object in Java so the default value for month is null

Recursive pass in object by reference? JAVA

So I have an algorithm that forces me to pass in an object as a parameter recursively and on different depths of the recursion it sets the values of the object. The problem is Java isn't allowing me to do this because they pass in by value or something else that is just messing me up. How can you make sure that the object passed in retains the value set?
You never pass an object as an argument in Java. You either pass a reference or a primitive value. The argument is always passed by value. Java doesn't have pass-by-reference at all.
If you're passing in a reference to an object, and you want to make sure the code you call doesn't change the data within that object, your options are:
Create a copy and pass in a reference to that instead
Make your type immutable in the first place.
EDIT: Just to make it clear, if you have:
Foo f = new Foo();
then the value of f is not a Foo object. It's a reference to a Foo object. If you now call:
doSomething(f);
then the value of f is copied as the original value of the parameter within doSomething. That behaviour is basically the definition of pass-by-value. There's nothing doSomething can to do change the value of f - it will still refer to the same object afterwards. The data within that object may have changed, but it won't be a different object.
In a real-world analogy: if I give you a copy of my address, you can go and paint the front door, but you can't change where I live.
As Jon states, all non-primitives are passed by passing a copy of the reference. You don't have a choice. So your recursive method should be able to update the object if it is mutable. HOWEVER, you can't reassign a reference and expect it to propagate back up the call stack. And remember that Strings are not mutable.
In other words, if you do the following, you have not changed the object that was passed:
void myMethod(Object o){
o = new Object();
}
The above changes the local reference to o but does not change the caller's reference to o. If you need to do something like this you would need to return o.

Categories

Resources