Object Instance Manipulation - java

If I have an Object instance, say a4, is there a way I could print out the name of the instance?
So with the instance a4, I would like my output to say a4.

Not stalking you I swear!
Short answer: No
Long Answer: Its impossible to get the name of a local variable using the reflection API as it is simply not available to the JVM. Have a look here: Java Reflection: How to get the name of a variable?
Its a hideously messy thing to attempt to do. Why are you trying to do it?

The simple answer is; if you want an object to have a name, give it a name field and add this field to the toString()
Local variables are only available in the debug information of a method. It is possible to read the byte code of a method and reverse engineer a name but this requires an extraordinary amount of work.
Consider
Object a1 = ...
Object b1 = a1;
The same object is referenced by two local variables. An object can be referenced in any number of places. e.g the empty string object is often the most referenced object in a Java program. It can appear in 10Ks places in a normal program.
I'm trying to add an array to a HashMap using a method that is only passed in a HashMap key. I take the key, extract an array already in the HashMap, make a clone of it, and then place that clone in the HashMap using the name of the instance as the key.
Say you pass an array into a method like
public void addArray(int... array) {
At this point the "name" of the reference to the array is array and it will not be anything difference.
What you need is to pass the name you want the array to have as there is no way for a caller to know what the callee used as a local variable. Often a variable has no name in the first place.
addArray(1, 2, 3);
or
addArray(calculateNumbers());
or
int[] nums = { 1, 2, 3 };
addArray(nums);
Note: nums is not actually needed as a local variable can be optimised away. i.e. There is a good chance nums won't even exist at runtime.
What you need to do is
public void addArray(String name, int... array) {
map.put(name, array);
}

Related

what is this concept called and from which version of java

Can you please let me know which version of java below flower bracket ({}) is introduced? what is concept name for this.
Object[] arg = {abc.getAbctNumber()};
here abc is object of java class and getAbcNumber() is a java method. I understand that arg object will be assigned with the value of return value of getAbcNumber() method.
{} is used to specify an array literal. So in your case you're specifying an array of objects with one element.
There is no such thing as a "flower bracket" in java. What you are seeing here, is an array being populated by a method.
You are creating an array with this syntax similar to:
int myarray[] = {1, 2, 3};
which will create an array of three ints. Your array will be created with an object.
This looks like a list initializer (not sure about the terminology, I don't do a lot of Java). In this case arg is an array of type Object and it's being initialized with a single value, which is the result of abc.getAbctNumber().
Consider an initializer with more than one value and it starts to become more clear:
Object[] arg = {
abc.getAbctNumber(),
abc.getSomeOtherNumber(),
abc.getSomethingElse()
};
That would initialize the arg array with three elements, the results of three different methods.
There is nothing called Flower bracket(at least I don't know about that). And in your Object[] arg = {abc.getAbctNumber()}; {} represent an array of one element and that element being an Object that is returned by method getAbctNumber()

When does a 'void' method affect the parameter, and when does it affect the original object?

I am brand new to programming, as well as to this website, so forgive me if I screw anything up. I'm having a heck of a time figuring out how to properly post my code in here.
package tester;
import java.util.*;
public class Mainclass2 {
public static void main(String[] args) {
int y = 3;
int[] x = {1, 2, 3, 4};
editnumbersArray(x);
editnumbersNotArray(y);
System.out.println(x[2]); **//now this was changed from 3 to 9...**
System.out.println(y); //but this one went unchanged.
}
//this accepts 'x[]' into the 'a[]' parameter.
public static void editnumbersArray(int[] a){
a[2] = 9; **//<---why does this one CHANGE the actual x[2] instead of just a[2]?**
}
//this accepts 'y' into the 'a' parameter.
public static void editnumbersNotArray(int a){
a = 9; **//<--while this one only changes 'a' instead of 'y'?**
}
}
So my question is basically typed in there as comments. Why does the array that is passed into the method change the values of the original array (x[]) when the int that is passed into the other method doesnt change? I'm sure it's a simple answer, but when I did my research I couldn't figure out what to search. I don't know what this is called so everything I searched led me the wrong way. Thanks for any help!!
EDIT: Thanks for that analogy with the address! That is by far the best way you could have explained it to me. So basically when you pass an array into a parameter, its passing a reference, not the actual value? So when I make adjustments within my method, its changing whatever the array is referencing?
I noticed that this also happens with a list. So the list isnt actually passed by value? It seems as if the array/list itself is basically passed in for editing, no matter what I name it within my method (a[] in this case.)
EDIT http://javadude.com/articles/passbyvalue.htm this page really cleared it up. And sorry for posting a duplicate question. The problem was that I didn't know what I was trying to ask. I had never even heard these terms "pass-by-value/reference", so now I know
Changing the value of the parameter itself never affects the argument in Java, because all arguments are passed by value. However, look at this method:
public static void editnumbersArray(int[] a){
a[2] = 9;
}
That assignment doesn't change the value of the parameter. The value of a is still the same reference, to the same array - it just changes the contents of the array.
Imagine if I wrote my home address on a piece of paper for you. It wouldn't matter what you did to that piece of paper - that wouldn't change where I lived. However, if you visited the address and painted the front door green, without ever changing the piece of paper at all, I would see that change.
It's very important to differentiate between different concepts:
A variable is a named storage location; it holds a value, which is always either a primitive value (e.g. an int) or a reference. In my example above, the piece of paper was like the variable.
A reference is just a value which allows you to navigate to an object. It's not the object itself. It's like the address on the piece of paper.
An object contains other variables. There may be several variables which all have values which are references to the same object. It's like the house in my example: I can write my address on several pieces of paper, but there's only one house.
An array is an object which acts as a container for other variables. So the value of a is just a reference to the array.
Java uses pass by value (what you want to search for) for everything. Essentially that means it makes a copy of the parameter that it then passes to the method. That means that you cannot change what something points at by using the = operator.
That is why the (int a) version doesn't change a.
However, in the case of an Object or an array it doesn't make a copy of the Object or array, it makes a copy of the reference to the Object or the array. That means that you have two variables, the original on and the, in your example, (int[] a) one that both point to the same spot in memory. Changes to either variable will affect the other variable.
Pass by value, pass by reference, and pass reference by value are the types of things you want to search on for more information.

Is it possible to change a variables value from an array

This is a little confusing question for me to express, but I'll do my best.
So:
ArrayList<Object> fieldList = new ArrayList<Object>();
I then dump a lot of different variables to this array:
fieldList.add(objectsURL); //string
fieldList.add(X); //int
fieldList.add(Y); //int
...
If I change the variable, the values in the array change
too-confirming the array stores a reference to the memory, rather
then value itself.
However, if I then retrieve data from the array then set that...
Object object = ((String)this.fieldList.get(0));
Then set object
object = "meeep!"
objectsURL is not set to "meep!" but rather it retains its original
value.
I assume this is because the "object" is not referencing the original
variable anymore, that instead its pointing to a new immutable string
in the memory.
All expected Java behavior I think....but then, how would I go about
setting the actual original variable? is this possible in java?.
So, in other words. Given only access to "fieldList" is it possible to change the value of
"objectsURL"?
So, if:
String objectsURL = "www.google.com"
fieldList.add(objectsURL);
Is there a way to set objectsURL to "www.stackoverflow.com" using only a reference from fieldList?
I dont want to change the fact that fieldList contains "objectsURL", I want to change what string the variable "objectsURL" actualy contains.
If not, is there an alternative method to achieve the same thing?
I hope my question explains the problem well enough.
My use-case is trying to make a serialization/
deserialization system for a bunch of my objects. I was hoping to put
all the fields into a arraylist I could retrieve for both reading and
writing....thus avoiding having to hard-code long lists of
field[0]=blah and blah=field[0] and then going though constant pains
of needing to renumber them each time I add a new field before
another.
(I cant use Javas inbuilt serialization, as I am using GWT and this is client side only.)
Thanks,
I assume this is because the "object" is not referencing the original variable anymore, that instead its pointing to a new immutable string in the memory.
Correct, each time you use the assignment operator = on an object you change the object it refers to, not the object itself.
To change the values in the List, you use the .set method of an ArrayList
this.fieldList.set(0, newValue);
Since your variable is a String, there is no way you can change the String-variable through the list
Your alternatives:
using a char-array
List myList = new ArrayList();
char[] charArray = "My String".toCharArray();
myList.add(charArray);
charArray[0] = 'A';
String theString = new String(myList.get(0)); // "Ay String"
If you use a char-array, make sure that the length of the array is enough to contain the number of characters you want to have in the future, because to change the length of the array you will need to create a new array (array lists can be expanded dynamically, arrays can not)
Embed the String inside your own class (I have ignored getters and setters here)
class MyString {
public String value;
public MyString(String value) {
this.value = value;
}
}
MyString myStr = new MyString("some value");
list.add(myStr);
((MyString) list.get(0)).value = "a new value";
System.out.println(myStr.value); // will print "a new value"
Strings are immutable, so it is impossible to change the contents of a String object. Also, you cannot use the list to change what object the reference variable objectsURL points to. To achieve what you want, you will need to create a custom class that has a String member. You can then store instances of this class in a List and change the String references to via the references in the list. The changes will then be reflected in any other reference variables which refer to the objects in the list.
First, you declare a variable 'object' and assign some Object out of the ArrayList. Later you assign some other object "meeep!" to this variable. There is no reason that your 'object' variable is related to the ArrayList.

Why do arrays change in method calls? [duplicate]

This question already has answers here:
Are arrays passed by value or passed by reference in Java? [duplicate]
(7 answers)
Is Java "pass-by-reference" or "pass-by-value"?
(93 answers)
Closed last month.
When I write like this:
public class test {
void mainx()
{
int fyeah[] = {2, 3, 4};
smth(fyeah);
System.out.println("x"+fyeah[0]);
}
void smth(int[] fyeah)
{
fyeah[0] = 22;
}
}
It prints x22;
When I write like this:
public class test {
void mainx()
{
int fyeah = 5;
smth(fyeah);
System.out.println("x"+fyeah);
}
void smth(int fyeah)
{
fyeah = 22;
}
}
It doesn't print x22, but prints x5.
Why, in the second version function, doesn't the value change? Does it change values only for array elements?
The fyeah variable in your first example contains a reference to an array (not an array), while the fyeah integer in your second example contains an integer.
Since Java passes everything by value the following will happen:
In the array case: A copy of the array reference will be sent, and the original array will be changed.
In the int case: A copy of the integer will be changed, and the original integer will not be changed.
It's because your int is a primitive and the method smth creates a local copy which is why it doesn't print the way you want. Objects are passed by value as well, but a value to the pointer in memory. So when it is changed, the pointer stays throughout both methods and you see the change. Read More Here
Ok. An int in java ( and really all languages that have strict data typing ) is a primitive data type. Its just a single variable of that data type. In java this means its passed by value to the method. So when you pass in the argument, a copy of the passed variable is created. Any operations that take place in the method act on that copy not the passed variable.
Actually in java EVERYTHING is passed by value but getting into the details of how that actually is true with what I am going to say next seems inadvisable.
With the array...its a collection of variables of the primitive data type int. So an entire copy of the array isn't actually made just a copy of the reference to the memory that stores the array. so yes the value of the int IN the array is changed from operations in the method.
In short methods don't change the external value of primitives (int,float,double,long,char) with the operations in the method, you have to return the resulting value of those operations to the caller if you wish to obtain it. Operations do change the value with most objects as well as with arrays of primitives. Hope that helps. Really unsure of how low level to get. Maybe someone else can clearly explain exactly why its by value. I "get" it but find it hard to help other people understand.
Think it in terms of memory: Lets analyse your first program -
In mainx , fyeah is an array of ints , so its a reference ( or a pointer if I may ). This reference points to a location in heap memory where the actual array of ints is stored. Lets say at address 100. Located contiguously from here are three ints ( lets say beginning at address 100 , 104 and 108 respectively are 2 ,3 and 4 ).
Now you call your method smth and pass the reference. Within the method , there is another reference ( of an int array type ) named fyeah. This fyeah is quite distinct from fyeah reference in the mainx method. Now , when you call smth and pass the fyeah from mainx , the fyeah within the smth method is initialized to point to the same location ( ie memory address 100 )
When you access the 0 element of fyeah and assign it a value of 22 , it reaches out to the memory location of 100 and writes this value 22 there. When you come back in your mainx method , the fyeah reference is still referring to memory address 100. But the value present at that location is now 22. So you get that value when you access the first element from fyeah in mainx.
Now , your second program. Your mainx method declares an int ( not an array , but a simple int ) and set it to 5. This fyeah variable is created on stack not on the heap. The value of 5 is stored on the stack. Now you call smth and pass this variable. Within the method smth , you again declare an int variable , fyeah by name ( as a formal method argument ). Again this is distinct from the fyeah of the mainx method and this fyeah is also created on stack.This variable will be initialized to a value of 5, copied over from the fyeah you passed to smth as argument. Note now that there are two distinct copies on fyeah variables , both on stack , and both a value of 5. Now you assign the fyeah in smth a value of 22. This will not affect the fyeah of the mainx method,so when you return to mainx and access fyeah , you see 5.
The int is a value type so 5 is passed directly into smth which can only modify the local copy. An array on the other hand is a reference type so the elements of that array can be modified.
Seeing it a bit less technically, I would say that
fyeah[0] = 22;
is changing the content of (the object pointed to by) fyeah, while
fyeah = 22;
is changing (the variable) fyeah itself.
Another example:
void smth(Person person) {
person.setAge(22);
}
is changing (the content of) the person while
void smth(Person person) {
person = otherPerson;
}
is changing the variable person - the original instance of Person is still unchanged (and, since Java is pass-by-value, the variable in the calling code is not changed by this method)

Android - Share Objects by Reference

hey people,
I have created a class which extends application to share certain variables. Within each activity I then use an object of that class (globalstate) as so:
gs = (GlobalState) getApplication();
I then declare local variable which reference the shared ones such as:
boolean localStr = gs.str;
Now I am under the impression this would be passed a a reference and therefore any change to localStr would be reflected in str within globalstate. However this does not seem to be the case.
Some variables created in this manor such as an array of object seem to be passed as reference and therefore any changes are reflected within globalstate however for almost every other variables (booleans, strings & ints) it seems the changes aren't reflected and therefore are being copied rather than referenced.
Have I done something wrong or is this how android works, if so how can i pass by reference? Thanks.
boolean is a value type, Java doesn't use a reference to store it. It's the same for all Java primitive types (int, long, ...). Strings are different, they are reference types but are immutable as explained by Johan Sjöberg.
That's why when using an ArrayList (for example) you will get an error if you try to use a value type like new ArrayList<boolean>(). But new ArrayList<Boolean>() will work because Boolean is a reference type, not a value type.
To avoid your problem you should use your reference everywhere (use gs.str instead of creating a local variable, localStr). I can explain it better if you don't really understand what I'm saying.
That's not only how android works, that's how java works. Strings are immutable, meaning they cannot be changed. Every time you try and modify a string a new string is created; hence the following code will leave the string named first unchanged:
String first = "first"; // First points to mem address e.g., 0x1
String second = first; // Second also does
second = "something else"; // Second now points to 0x2, first still to 0x1
It's exactly the same behaviour for all primitive types (int, boolean etc).
However, when you pass a List of objects, alterations of the list contents will be changed everywhere. This is since your objects share the same list reference (which itself doesn't change, only it's contents).

Categories