Object reference clarifcation - java

Please correct me if I am wrong, I just want some clarification that I'm understanding this right.
When you create an object in java you use the new keyword followed by the class type. Ex. new [someclassnamehere]();
Depending on your constructors you can pass arguments by supplying them in the parameter when you create the object.
I'm not sure if it would ever be useful to just have a line of code that creates a new object o by just using the new keyword, because nothing is actually holding the reference to that information. But it's correct it seems.
So you can create a variable that contains the reference to the new object you are creating by using type name.Such as: Employee someData; . But it has yet to actually reference an object, seeing as one hasn't been created yet. So by applying the above information discussed:
Employee someData = new Employee(name);
We now created an Employee object that contains some name of the employee. The new keyword created an instance of the class Employee, an object, in which the someData variable references that newly created object.
So now the someData variable can be said to reference the Employee object because it contains the address in memory of where the object is stored. This address will allow us to access the actual data of the object, in this case the name of the employee.
If I were to create an ArrayList that has the datatype Employee, I can store Employee objects in it. So I can add the someData variable to the arrayList as well as someData2,someData3,etc. (Just assuming they are all of the same type but contain different employee information).
So each of those variables contain references to these objects. The ArrayList object then contains references to these objects as well because the ArrayList elements contain these someData variables which reference the Employee Objects.
example:
ArrayList.get(1) -> someData -> reference variable(address) -> employee Object
ArrayList.get(2) -> someData2 -> reference variable(address) -> employee Object2
Pretty sure I got the idea down so far, but what slightly throws me off is when you actually don't create a reference variable.
So let's say you create a loop which creates an object(data is being read from some database,etc) and adds it to an ArrayList. In this loop you collect the data you want and use that to create an object, which is then directly added to an ArrayList.
Let's say it looks like this (combination of some pseudo code and actual code)
ArrayList<Employee> list = new ArrayList<Employee>();
// While data from the database still exist (while loop,etc)
// extract some sort of data from the database, such as their name and hours
// create an object of this information and store it in an ArrayList
list.add(new Employee(name, hours);
// end loop
For simplicity, let's said the loop ran 5 times so it created 5 objects.
This means it added 5 objects to the ArrayList List and the references to these objects are actually contained in the ArrayList elements. So to get the first object added to the ArrayList you would use list.get(1) (I'm pretty sure ArrayList start at 1 and not 0 for indexes), which returns the reference to that object.
EDIT: Please forgive me for my mistake here, I suppose I had a brainfart and got mixed up. I don't know why I thought ArrayList indexes worked like that for a second
Is this correct and standard way of creating objects through the use of a loop?

I'm not sure if it would ever be useful to just have a line of code that creates a new object o by just using the new keyword, because nothing is actually holding the reference to that information. But it's correct it seems.
Imagine that the constructor starts a new thread. No reference, but
new AmazingThread();
is fine in that case.
Well, this question is huge. And yes, creating objects like this is completely legit. You can think of ArrayList having it's own variable storing the reference.

Related

How to create a generic number of objects?

I am currently thinking about how to create n objects of type x in Java.
Thought experiment: You want to create all entries from a specific database table as an object.
The number of entries are given by counting them.
The object to be created is a model of a table entry.
My current strategy would be to create Lists foreach column.
After that, I would create an Object by looping through the Lists, append it to a HashSet and continue with the next row.
But probably there is a problem with the references, because the created objects would have the same name and if I remember right, I would overwrite the pointer by creating another object in this case. So it's the question if the HashSet still contains the old reference or not.
Besides this solution would be very ineffective cause of the number of loops.
Pseudocode
HashSet for objects
lists of every column
iterate through lists
create object with values at position i of loop
append object to HashSet
If you have a clue about to solve the pointer problem or if it does not exist, I would be glad about your answer. Moreover, I would be grateful for more suited solutions.
PS: I did not found any design pattern for this use case
If I'm correctly understanding the "pointer problem" to which you refer, it does not exist. I think you may have some misconceptions about how references, as they are properly called in Java, work.
Take the following code
Set<MyObject> mySet = new HashSet<>();
MyObject myOb;
myOb = new MyObject("Object #1"); // 1
mySet.add(myOb); // 2
myOb = new MyObject("Object #2"); // 3
mySet.add(myOb); // 4
At the lines marked // 1 and // 2 we create a MyObject object with the data "Object #" and add it into a Set; the variable myOb references the object we've just created.
If we were to print the contents of the set at this point, we'd see
{["Object #1"]}
At line // 3, we create another new MyObject object, this time with the data "Object #2", and assign myOb to reference it.
But wait! We've just added myOb (which was referencing an object with the data "Object #1") to the set, and now we're changing myOb to reference a different object. Does that mean our set suddenly looks like:
{["Object 2"]}
No, it doesn't, because what was added to the set was not myOb itself, but the rather the myObject object that myOb happened to be referencing at the moment that mySet.add(myOb) was called. All the set received was a reference to a MyObject instance; it hasn't the slightest clue that the reference happened to be stored in the variable myOb.
Thus we can make myOb reference (or "point to", if you prefer) any other MyObject object (or even the same object again) without affecting the set in the slightest.

Rename object names in methods

I've got a piece of code
list.add(new Person())
Since the Person object is missing it's naming part
Person p = new Person()
What kind of name does this person object get assigned to?
Is it important to know the name of the object?
How would I go about accessing this object's methods if it is added to the ArrayList without a name?
edit: name == reference. I know objects don't have names
p is not "the name of the object". p is a variable that happens to hold a reference to the Person object. Objects don't have names.
If you skip declaring the p variable and add the Person object directly to the ArrayList, the ArrayList still holds a reference to that object, so it doesn't matter whether you use list.add(new Person()) or list.add(p).
Either way you can retrieve the reference to the Person with list.get(index), and then execute any methods you wish.
I think, that the name of the Person-Object doens't matter.
You can simply access it with list.get(int number).
This will give you the refernce to the element at the position.
Hope I understood your question correctly and this helps you.
The name is only used by developers for reference, it's not actually needed at runtime.
To access your object you'd use:
List<Person> list = new ArrayList<Person>(); // Create the list
list.add(new Person()); // Add the person to the list
list.get(0); // Returns the person you added
If you want to get specific people from your list I'd suggestion using a HashMap and store their names as the keys.
I think you may be confusing the creation of an object with assigning a reference to that object. In you example p is a reference to the object Person that you have created. You have not named that object p, but have a reference called p to the object person.
To create a reference to the person object from list.add(new Person()) you simply do a
Person p = list.get(0)
You can access the object from its index in the List.
An object lives in JVM memory heap, and doesn't have such a thing as a name. It can be referenced by variables that can be lists or single elements. In the case of the list you can reference the object by accessing the list element by its index.

Storing objects in array of objects

Basically i want to add students to a class list. Assuming i have the following code
public class ClassList {
//Constructor methods...
private Student [] studList = new Student [20];
public boolean addStudent (Student newStudent)
{
studList[14] = newStudent;
}
}
Does studList[14] add a reference to newStudent object or copies that object into the studList[14] student object?
As far as i understand newStudent object will get deleted when the method addStudent() is called a second time. So studList[14] will point to null then? What if i want studList[14] to persist throughout the code execution?
Sorry if it is hard to understand, i do not know how to explain my query easier...
There's one fundamental rule in Java that you have to wrap your head around:
The only way you can access an object is via its reference. And the only values that variables can hold are references(*). That's true for local variables, parameters, instance fields and static fields: they all are the same in this respect.
The object itself is never "contained" in a variable.
This directly leads to the answer to your first question:
The reference is copied into the array (as an array can only hold references(*), never objects).
This also mean that "newStudent being deleted" is not actually a big deal: it's just another reference to the same object, and if it goes away nothing much happens.
Now, if all references to a given object are removed (or no longer reachable), then the object itself becomes eligible for garbage collection, but that's not a bad thing, because you could not access it anymore anyway.
(*) ... or primitive values, but we'll ignore those for this dicussion.
The assignment doesn't copy the object. It just adds a reference to the object into the array.
An object gets deleted by the garbage collector after there are no more references to it anywhere. You don't need to worry too much about this process, because it's kind of invisible most of the time; and once there are no references to an object, you couldn't have used it anyway.
Perhaps you want to be able to pass in an int to your method, to tell it which entry in the array to set, instead of always setting entry number 14?
You should have a look at the JLS about types, values and variables:
The values of a reference type are references to objects.
If there is no remaining reference (aside weak ones) to an object it will be garbage-collected out of the heap.
If you call two times: addStudent(new Student());
the first Student object created is qualified for GC since you have no other reference variable "pointing" to the object.

Java collections and memory use

I have a question on Java memory use. It’s for my edification and anyone else who searches and finds this later! For the purpose of the question, please assume, this is a single method and nothing goes out of scope... during my question ;-)
I have created 5 new objects with a single property called ‘name’ of type String.
I create an ArrayList and add the 5 objects to the ArrayList. I then create a HashMap and iterate through the previously created ArrayList, adding the objects to the HashMap.
Q1. When I add the objects from the ArrayList, to the HashMap, I assume I am just creating another collection of ‘pointers’, since I’m not using the ‘new’ keyword. Therefore no new memory is consumed, except for the HashMap itself (the objects are not duplicated).
Q2. If I change the value of ‘name’, in an object in the HashMap, would the same change be seen, if I were to iterate over the ArrayList, after making the change.
I appreciate a ‘sanity check’ on my understanding.
Q1: The HashMap is created and the references to the objects are created. So memory is consumed, but references aren't terribly big, but can make a difference if the number of references is huge.
Q2: Edit: Yes, the name field would change. Better still, write a small program to check it out.
A1 : Yes, other than the references and HashMap, nothing new will be created. (Assuming you are not creating a new set of keys for for the HashMap)
A2 : Yes, the change will reflect on the ArrayList.
To answer your questions.
1.) When you add objects to a HashMap the objects are not duplicated. Internally though the map will create new objects to maintain its inner structure. The inner structure of a map consists of HashMap.Entry objects that contain a linked list with all values that map to the same hash code. Thus whenever you add objects to a map one or more internal objects are created.
2.) I assume you stored the objects in the HashMap using their name as key. In this case chaning the name of an object will update the object (no matter whether it's being accessed through the list or the map, it's always the same object) but not the mapping in the map. In the map the object will still be store under its old name!
Map map = new HashMap();
Foo f = new Foo();
f.setName("A");
map.put(f.getName(),f);
f.getName(); // => "A"
map.get("A"); // => f
f.setName("B");
f.getName(); // => "B"
map.get("B"); // => null
map.get("A"); // => f

When adding a object to a java collection is it added by value or reference?

I've looked around and cannot figure this one out: I have a object that implemens an observer pattern and a List implementation that allows listeners to be added on the list whenever a change event is triggered on any object in the list to avoid manual add/remove listeners to each object int the list.
The problem I have is when creating a new instance of the same List implementation and adding objects from existing lists the object changes are not getting triggered from beans added to the new list. My thought was that when adding an object to a Collection it just adds a pointer to the existing object which given this case the change notifications would be getting triggered on objects in the new list but this is not happening. Can anyone help me figure out what the problem might be? I have seen similar questions but none that can help me solve this problem.
The use case, is a stock scanner where one list has all the stocks in the market I'm watching and the scanner list only has the stocks that pass the criteria but the scanner is not getting updates like price, volume etc that get triggered using the observation pattern. - Duncan
Your understanding was correct; collections hold references to objects. For example, this:
final StringBuilder stringBuilder = new StringBuilder();
final List<StringBuilder> stringBuilderList = new ArrayList<StringBuilder>();
stringBuilderList.add(stringBuilder);
stringBuilderList.add(stringBuilder);
stringBuilder.append("yes");
System.out.println(stringBuilderList);
will print this:
[yes, yes]
because there was only a single StringBuilder instance, so the appended "yes" is in every element of the list.
But note that the collections hold those references by value, not by reference. For example, this:
StringBuilder stringBuilder = new StringBuilder("yes");
final List<StringBuilder> stringBuilderList = new ArrayList<StringBuilder>();
stringBuilderList.add(stringBuilder);
stringBuilder = new StringBuilder("no");
// now stringBuilder refers to a different object than before
stringBuilderList.add(stringBuilder);
System.out.println(stringBuilderList);
will print this:
[yes, no]
because the two elements of the list refer to different objects, even though both objects were identified by the same variable.
For more help in figuring out what's going wrong with your code, I think you'll have to post a minimal program that demonstrates the issue.
By value, always!
When it comes to objects, the value passed is the value of the reference, but not the reference it self.
See most of these links
Languages where pass by reference is supported ( Java doesn't support this ) can perform the following:
Foo foo = new Foo();//create a new object
foo.name("Old foo"); // label it
modify( foo ); // try to modify it
// In a language that supports byRef will print "New foo".
// In Java will print "Old foo" always
println( foo );
...
void modify( Foo foo ) {
foo = new Foo(); // reference assigned a new different object
foo.name("New foo");
}
So, languages that support pass by reference, will put the new object created inside the method to the reference passed to them ( they receive the reference after all ). Languages like C++ and VB can do this..
Languages that doesn't support pass by reference ( like Java ) won't assign the new object to the original reference, Java will assigned it to the copy of the reference ( the one created in the argument passing --> void modify( Foo foo ) { ) But the original one, the one created before the method will remain intact and thus still with Old foo.
As per java spec, everything passed as value in Java. This SO discussion has very good example explanation on how it works. Specifically read second answer.
Yes, in Java every class (but not simple types) is been passed by reference.
To solve your problem, you can use clone, if your objects support it.
Java objects are always passed by reference.
So, unless your Collection's "add" method does something else (like cloning the object or using it as a prototype, etc) everything should be working.
I think your issue is more on the notification's logic than within the collection itself. I suggest you paste some code.

Categories

Resources