Passing an object as a parameter in Java - java

There is a scenario
Say I have a class People & a utility class PeopleUtil with a method computeTotalNumberOfPeople
In a separate class say EvaluatePeople where I have code
People people = new People();
people.setValue(10);
people.setX(45);
PeopleUtil.computeTotalNumberOfPeople(people);
this.persistPeople(people);
In the computeTotalNumberOfPeople method
public void computeTotalNumberOfPeople(People people){
//logic for computing total no of people & then
int totalPeople = certainIntValue;
// I can return the totalPeople value from this method but I am not doing it just for the sake of this scenario
people.setTotalNumberOfPeople(totalPeople);
}
When I look at the People object in the db row I see the totalNumberOfPeople value persisted. Which is actually fine.
My question is, I am a little confused about it, shouldn't computeTotalNumberOfPeople method return the people object, which has an extra set value, to the method caller code & then that object should be passed to the peristPeople method as an argument?
I hope you understand what I mean, it doesn't seem right someway

Objects are mutable – they can be changed.
So when you call people.setTotalNumberOfPeople(totalPeople), you are setting the totalNumberOfPeople variable (or whatever it's called inside the People class) to totalPeople for the people object.
When you exit the computeTotalNumberOfPeople method, the object is still the same one that was modified – the changes from the method persist.
One way to think about it is passing a reference to people. When you call computeTotalNumberOfPeople(people), you are passing a reference to people. When people is modified, you modifying the same location in memory, and so the changes persist.

Related

Does Java's pass-by-valueness mean I do not need a deepCopy function for my class?

I am having a rough time getting some of my code to work. The code starts a SwingWorker and gets the results. I am having trouble passing data to the worker and getting information back from the worker.
The data I want to pass is made up of objects of classes I defined myself. For example I have both an Item and Inventory object. The Item object contains basically all primitive types (name, price, etc) and the Inventory contains a LinkedList of Items.
I can't quite remember the series of events that lead up to my sanity check, but as a sanity check I implemented Item.getDeepCopy(Item inItem) and Inventory.getDeepCopy(Inventory) functions so that I could pass copies of Items and Inventorys to my workers. Is this needed?
How I use the deep copy functions is when I pass data to and get data from my StringWorkers. Say I launch a worker as a result of a button click. In the event handler I first get a deep copy of my classes private local copy of Inventory or Item and pass that to the workers constructor. Is this correct? Do I need to pass a deep copy? I think not..
I do this out of fear that the worker will try to modify the classes reference to the object within the worker itself causing some threading issues. But after some reading and critical thinking this couldn't be the case because java is pass-by-value, so what is passed to the worker cannot possibly lead to the GUI components data changing. Is this correct thinking?
Then when the worker is done, it calls an overridden done method I wrote. This method runs on the EDT so I can call functions from my GUI component, namely a function I call WorkerDone(boolean result, Inventory outInv). The worker calls this function and passes (not a deep copy) its local copy of Inventory or Item back to the GUI. When the GUI gets it it then performs a deep copy and sets its local Inventory or Item to this value. Is this a good use for the deep copy?
Edit: A little more.
Basically I want to pass "some data" to the worker and allow it to work on it with no link to the GUI components. When the worker is done it will either have finished successfully or not. If successful I want to get the data "back" from the worker and update my local copy with the data returned. I don't want the worker to "touch" any of the data in the GUI.
For mutable-ness. I want to be able to change the data within the object after it is created. This is how I build my application with this in mind. What I want is not non-mutable objects to keep things thread safe, I just don't want threads interacting. I want to pass the worker some data and basically "forget that I sent it" and then when the worker is done and it calls the GUI's workerDone method the GUI simply just agrees to set its local copy of the data to the value of the returned object if the worker says it was successful.
Edit 2:
Just for clearer understand of the phrases pass-by-value and pass-by-reference. What I think when I see pass-by-value. Say I want to pass an apple by value, to do this I would put my apple in a cloning machine that makes an exact clone of the apple same in every respect and pass that apple. Whomever is passed this cloned apple can do anything with it, and none of it affects my initial apple.
What I think of when I see pass-by-reference is that if I want to pass my apply by reference I write down where my apple is on a piece of paper and then pass that. Whomever receives this piece of paper can then come to where my apple is and take a bite of it.
So my confusion comes from "Java is pass-by-value", if it is, then why do I have to worry about my worker causing thread violations when operating on the value passed to it?
Java is pass by value, but when you pass an object, you are passing a reference, and just a copy of that reference. Both references, the original and copy still refer to the same set of values in the heap.
It's valid to worry about code you have no control over possibly modifying your objects, but you could perhaps wrap that object in another that cannot be changed, or specify an interface that has the extract methods but not set methods.
Having the GUI have it's own copy of data could be useful if you might update the data, and halfway through updating the data you display it. If you have no worry about such inconsistencies, you may just want to share the same reference between the gui code and non-gui code to keep your code simple (assuming your classes here are thread-safe).
"Pass by value" and "pass by reference" describe how function arguments are passed on the stack. They have nothing to do with what can or can't happen to objects on the heap. Suppose that we write code in some completely made-up programming language:
def foo(x) :
x = 5;
end
def bar() :
a = 3;
foo(a);
print a;
end
What will the function bar() print? The answer depends on whether the parameter x in foo() is pass-by-value or pass-by-reference. In a pass-by-value language (e.g., in Java), the value of the local variable a is passed when bar() calls foo(a). The foo() function can modify its own copy of that value, but it can not modify the caller's local variable, a.
In a pass-by-reference language, the address of the caller's local variable is passed. The x in foo becomes an alias for the a in bar(), and the assignment, x=5 changes the value of the variable a in bar.
Java is always pass by value: A Java function can never, ever, modify its caller's local variables.
Where people get confused is, a Java value can either be a primitive type (int, double, char, ...), or it can be an object reference.
public javaFoo(MyType x) {
x.setFrobber(true);
}
public javaBar() {
MyType mt = new MyType();
foo(mt);
System.out.println(mt.toString());
}
The variable x in javaFoo() is a different variable from the variable mt in javaBar(), and "pass-by-value" means that the javaFoo() function can not change mt. BUT both variables refer to the same object, and javaFoo() can modify the object.
"Pass by value" means that an object reference is passed. A copy of the original reference, not a copy of the object's data.
In other words, all your callees see the same object (and can change it at will).
Here's a good article from the Oracle Java docs on strategies for making an object "immutable":
http://docs.oracle.com/javase/tutorial/essential/concurrency/immutable.html

Passing big objects references instead of small objects to methods have any differences in processing or memory consumption?

I have a coding dilemma, and I don't know if there's a pattern or practice that deals with it. Whenever I have to pass some values to a method, most times I try to pass only the needed objects, instead of passing the objects which are being composed by them.
I was discussing with a friend about how Java manages heap and memory stuff and we didn't get anywhere.
Let me give two examples:
//Example 1:
private void method doSomething(String s, Car car, boolean isReal){...}
...
String s = myBigObject.getLabels.getMainName();
Car car = myBigObject.getCar();
boolean isReal = myBigObject.isRealCar();
doSomething(s, car, isReal);
//Example 2 - having in mind that BigObject is a really big object and I'll only use those 3 atributes:
private void method doSomething(BigObject bigObject){...}
...
doSomething(myBigObject);
In the 2nd example, it seems to me memory will be kind of wasted, passing a big object without really needing it.
Since Java passes only references to objects (and copies them, making it technically pass-by-value), there is no memory overhead for passing "big objects". Your Example 1 actually uses a little more memory.
However, there may still be good reason to do it that way: it removes a dependency and allows you to call doSomething on data that is not part of a BigObject. This may or may not be an advantage. If it gets called a lot with BigObject parameters, you'd have a lot of duplicate code extracting those values, which would not be good.
Note also that you don't have to assign return values to a local variable to pass them. You can also do it like this:
doSomething(myBigObject.getLabels().getMainName(),
myBigObject.getCar(),
myBigObject.isRealCar());
You're already only passing a reference to BigObject, not a full copy of BigObject. Java passes references by value.
Arguably, you're spending more memory the first way, not less, since you're now passing two references and a boolean instead of a single reference.
Java uses pass by value, when ever we pass an object to a method keep in mind that we are not going to pass all the values store in side the object we just pass the bits( some thing like this ab06789c) which is the value of the address on which the object is stored in memory(Heap Memory). So you are wasting more memory in first case rather than the 2nd one. Refer to JAVA pass-by-reference or pass-by-memory
All references are the same size, so how could it use more memory? It doesn't.

Most efficient way to pass a Java object around?

I'm considering creating the following method:
public static MyBigCollection doSomeStuff(MyBigCollection m) { ... return m; }
and then in another method (perhaps in another class), using it like so:
MyBigCollection mbc = new MyBigCollection();
mbc = stuffClass.doSomeStuff(mbc);
Am I going about this the right way -- is this an efficient way to "do some stuff" to an object? I'd like to break off the stuff like so for extensibility. I've been doing c# for so long I'm just not sure with java. In c# the method could return void and I can simply call doSomeStuff(mbc) -- which would effectively pass my object by reference and do some stuff to it. I've been reading that java works differently so I wanted to check with the experts here.
I'd refactor to:
stuffClass.doSomeStuff(mbc);
(i.e., a method that modifies mbc and returns void)
Keep in mind that all Java Objects are stored in heap memory, and passed around with reference pointers.
The way you're doing it is fine, but you don't actually need to return the object at the end of the method. As such, the following would be simpler...
MyBigCollection mbc = new MyBigCollection();
stuffClass.doSomeStuff(mbc);
Objects in Java are passed by reference, so any modification on the mbc Object in the doSomeStuff() method would still be retained in the mbc variable after the end of the method call.
The only reason why you might consider returning the mbc Object is if you want the ability to join multiple methods together, such as this...
MyBigCollection mbc = new MyBigCollection();
mbc.doStuff1().doStuff2().doStuff3();
In this case, because mbc is returned by each of the doStuff() methods, the next method can be called straight back on to the same Object. Without returning the reference, you'd have to do something like this instead...
MyBigCollection mbc = new MyBigCollection();
mbc.doStuff1();
mbc.doStuff2();
mbc.doStuff3();
Which is the same thing, but not quite as compact. How you go about it really depends on how you intend to use the methods and the Object itself.
There's only one way to pass Java objects around. Java passes everything by value. Objects aren't passed; they live on the heap. You pass references around, not objects.
Same as C#, as far as I know.
This kind of micro-optimization is usually meaningless.
I think your question is around how Java passes references to objects. Java passes by value, which can be confusing when first said. For objects, this means that the value of the reference to the object is passed to the method. Interacting with the object referred to by the value will alter the object 'passed in', so you don't need to return it.
Strings are treated differently as they are immutable. Primitives are also pass by value, but as the value passed is not a reference, you will not alter the original variable.
The easiest way to test this is to write some code and observe (you might also consider the Java tutorials)

Is it a good practice to change arguments in Java

Suppose I am writing a method foo(int i) in Java.
Since i is passed by value it is safe to change it in foo. For example
void foo(int i) {
i = i + 1; // change i
...
}
Is it considered good or bad practice to change arguments of methods in Java?
It's considered bad practice in general, though some people overlook it as you can see in the other answers.
For parameters like primitives that are directly passed in by value, there is no advantage in overriding the original variable. In this case you should make a copy as suggested by #João.
For parameters whose reference is passed in by value (objects), if you modify the handle to point to a different object, that is downright confusing. It's all the more important because modifying the contents of an object passed as a parameter will modify the original object too.
If you replace the object referred to by the handle, and then modify its contents, the object referred to by the original reference in the caller will not be replaced, but someone reading the code might expect it to be.
Whereas if you don't replace the object, and modify the contents, the method calling your method might not expect this change. This category generally comes under security-related bad practices.
It's merely a personal opinion, but I think it can be confusing for other people that may want to use the original parameter value later in that code, and may not notice that it has already been changed.
Plus, it's cheap to simply create another variable and assign it the modified value (i.e., int j = i + 1).
Since i is passed by value it is safe to change it foo()
It is absolutely safe even when you pass an object reference because they are local: i.e., assigning a new reference to the local reference will not have any impact on the original reference in the calling code
It's your personal choice. However i would not change the argument values as one might loose the track of the actual value passed in to this method.
What is important to note is that i = i + 1; does not really change i. It only changes your local copy of i (in other words, the i in the calling code won't change).
Based on that, it is a matter of readability and avoiding unexpected behaviour in your code by complying with the POLS (Principle Of Least Surprise).
Neutral. But it would be considered a better practice by many people to change the method to:
void foo(final int i) {
int j = i + 1; // not change i
...
}
Feel free to work either way.
Depends on context. I lean towards "bad practice", for two reasons:
Some people may think the original value is being changed.
It may make the code harder to reason about (mitigated with appropriately-short methods).
A third issue pops up when it's a reference value. If you modify the parameter reference to point at something else and change its state, the original won't be modified–this may or may not be what's intended. If you create another reference to the parameter and change the new reference's state, the parameter's reference will be changed–which also may or may not be what's intended.

Can a class be nullified from within the class itself?

For example, is this code valid?.
class abc{
int x,y;
abc(int x,int y){
this.x=x;
this.y=y;
while(true)
update();
}
public void update(){
x--;
y--;
if(y==0)
this=null;
}
}
If the above is not valid, then please explain why. I am in need of a class that after certain iterations ceases to exist. Please suggest alternatives to the above approach.
No, this code is not valid.
Furthermore, I don't see what meaningful semantics it could have had if it were valid.
Please suggest alternatives to the above approach.
The object exists for as long as there are references to it. To make the object eligible for garbage collection you simply need to ensure that there are no references pointing to it (in your case, this should happen as soon as y reaches zero).
No. The reason is that you do not make object null. When you say obj = null; You just put null to variable that previously hold reference to object. There are probably a lot of other references to the same object.
I think that what you want to do is to kind of invalidate object and make it garbage collected but take this decision inside the class. If this is the problem I'd recommend you to take a look on weak references.
Other possible solution is to implement kind of "smart reference" in java. You can create your class SmartReference that will hold the real reference to the object. The object should hold callback to this smart reference and call its method invalidate() that is something like your syntactically wrong expression this = null. You have to care not to refer to such objects directly but only via smart reference.
The only question is "why do you want to do this?". Really, this will cause the code to be more complicated and unstable. Imagine: the object decides to invalidate itself, so the reference that "smart reference" is holding becomes null. Now all holders of this smart reference will get NPE when trying to use the object! This is exactly the reason the such mechanism does not exist in java and that application programmer cannot mange the memory directly.
Bottom line: remove all object references and let GC to do its hard job. Trust it. It knows to clean the garbage.
I think this is a good question.
I've had loads of cases where I'd like Objects to validate themselves after/during construction and if it finds reason to, to just return an empty value or go back up the stack and skip over creating that object.
Mostly in the case of where you are creating a list of objects from a list of other values. If a value is garbage and you want your object to recognise this.
Rather then have to code a function outside the Class itself to validate the creation, it would be much neater to allow the object to do it.
It's a shame java doesn't allow for things like this on the assumption the programmer is probably going to mess it up. If you code well it would be a nice feature.
I think you need to rethink why you want to do this, because what you're suggesting doesn't even exist as a concept in Java.
The this variable always refers to the object itself. You can't "nullify" an object, only a reference (since after all, what you're doing is assigning a reference to point to null instead of its previous object). It wouldn't make sense to do that with this, as it's always a pointer to the current object in scope.
Are you trying to force an object to be destroyed/garbage collected? If so, you can't do that while other parts of your code still have references to it (and if they don't have references, it will be garbage collected anyway).
What did you hope/think this would do, anyway?
your code must be get compile time error..
Coz..
The left-hand side of an assignment must be a variable
this is not a variable its a keyword..
this=null;

Categories