How do I multiply 10 to an Integer object and get back the Integer object?
I am looking for the neatest way of doing this.
I would probably do it this way:
Get int from Integer object, multiply it with the other int and create another Integer object with this int value.
Code will be something like ...
integerObj = new Integer(integerObj.intValue() * 10);
But, I saw a code where the author is doing it this way: Get the String from the Integer object, concatenate "0" at the end and then get Integer object back by using Integer.parseInt
The code is something like this:
String s = integerObj + "0";
integerObj = Integer.parseInt(s);
Is there any merit in doing it either way?
And what would be the most efficient/neatest way in general and in this case?
With Java 5's autoboxing, you can simply do:
Integer a = new Integer(2); // or even just Integer a = 2;
a *= 10;
System.out.println(a);
The string approach is amusing, but almost certainly a bad way to do it.
Getting the int value of an Integer, and creating a new one will be very fast, where as parseInt would be fairly expensive to call.
Overall, I'd agree with your original approach (which, as others have pointed out, can be done without so much clutter if you have autoboxing as introduced in Java 5).
The problem with the second way is the way Strings are handled in Java:
"0" is converted into a constant String object at compile time.
Each time this code is called, s is constructed as a new String object, and javac converts that code to String s = new StringBuilder().append(integerObj.toString()).append("0").toString() (StringBuffer for older versions). Even if you use the same integerObj, i.e.,
String s1 = integerObj + "0";
String s2 = integerObj + "0";
(s1 == s2) would be false, while s1.equals(s2) would be true.
Integer.parseInt internally calls new Integer() anyway, because Integer is immutable.
BTW, autoboxing/unboxing is internally the same as the first method.
Keep away from the second approach, best bet would be the autoboxing if you're using java 1.5, anything earlier your first example would be best.
The solution using the String method is not so good for a variety of reasons. Some are aesthetic reasons others are practical.
On a practical front more objects get created by the String version than the more normal form (as you have expressed in your first example).
On an aesthetic note, I think that the second version obscures the intent of the code and that is nearly as important as getting it to produce the result you want.
toolkit's answer above is correct and the best way, but it doesn't give a full explanation of what is happening.
Assuming Java 5 or later:
Integer a = new Integer(2); // or even just Integer a = 2;
a *= 10;
System.out.println(a); // will output 20
What you need to know is that this is the exact same as doing:
Integer a = new Integer(2); // or even just Integer a = 2;
a = a.intValue() * 10;
System.out.println(a.intValue()); // will output 20
By performing the operation (in this case *=) on the object 'a', you are not changing the int value inside the 'a' object, but actually assigning a new object to 'a'.
This is because 'a' gets auto-unboxed in order to perform the multiplication, and then the result of the multiplication gets auto-boxed and assigned to 'a'.
Integer is an immutable object. (All wrapper classes are immutable.)
Take for example this piece of code:
static void test() {
Integer i = new Integer(10);
System.out.println("StartingMemory: " + System.identityHashCode(i));
changeInteger(i);
System.out.println("Step1: " + i);
changeInteger(++i);
System.out.println("Step2: " + i.intValue());
System.out.println("MiddleMemory: " + System.identityHashCode(i));
}
static void changeInteger(Integer i) {
System.out.println("ChangeStartMemory: " + System.identityHashCode(i));
System.out.println("ChangeStartValue: " + i);
i++;
System.out.println("ChangeEnd: " + i);
System.out.println("ChangeEndMemory: " + System.identityHashCode(i));
}
The output will be:
StartingMemory: 1373539035
ChangeStartMemory: 1373539035
ChangeStartValue: 10
ChangeEnd: 11
ChangeEndMemory: 190331520
Step1: 10
ChangeStartMemory: 190331520
ChangeStartValue: 11
ChangeEnd: 12
ChangeEndMemory: 1298706257
Step2: 11
MiddleMemory: 190331520
You can see the memory address for 'i' is changing (your memory addresses will be different).
Now lets do a little test with reflection, add this onto the end of the test() method:
System.out.println("MiddleMemory: " + System.identityHashCode(i));
try {
final Field f = i.getClass().getDeclaredField("value");
f.setAccessible(true);
f.setInt(i, 15);
System.out.println("Step3: " + i.intValue());
System.out.println("EndingMemory: " + System.identityHashCode(i));
} catch (final Exception e) {
e.printStackTrace();
}
The additional output will be:
MiddleMemory: 190331520
Step2: 15
MiddleMemory: 190331520
You can see that the memory address for 'i' did not change, even though we changed its value using reflection.
(DO NOT USE REFLECTION THIS WAY IN REAL LIFE!!)
Related
I know this is probably very stupid, but a lot of places claim that the Integer class in Java is immutable, yet the following code:
Integer a=3;
Integer b=3;
a+=b;
System.out.println(a);
Executes without any trouble giving the (expected) result 6. So effectively the value of a has changed. Doesn't that mean Integer is mutable?
Secondary question and a little offtopic: "Immutable classes do not need copy constructors". Anyone care to explain why?
Immutable does not mean that a can never equal another value. For example, String is immutable too, but I can still do this:
String str = "hello";
// str equals "hello"
str = str + "world";
// now str equals "helloworld"
str was not changed, rather str is now a completely newly instantiated object, just as your Integer is. So the value of a did not mutate, but it was replaced with a completely new object, i.e. new Integer(6).
a is a "reference" to some Integer(3), your shorthand a+=b really means do this:
a = new Integer(3 + 3)
So no, Integers are not mutable, but the variables that point to them are*.
*It's possible to have immutable variables, these are denoted by the keyword final, which means that the reference may not change.
final Integer a = 3;
final Integer b = 3;
a += b; // compile error, the variable `a` is immutable, too.
You can determine that the object has changed using System.identityHashCode() (A better way is to use plain == however its not as obvious that the reference rather than the value has changed)
Integer a = 3;
System.out.println("before a +=3; a="+a+" id="+Integer.toHexString(System.identityHashCode(a)));
a += 3;
System.out.println("after a +=3; a="+a+" id="+Integer.toHexString(System.identityHashCode(a)));
prints
before a +=3; a=3 id=70f9f9d8
after a +=3; a=6 id=2b820dda
You can see the underlying "id" of the object a refers to has changed.
To the initial question asked,
Integer a=3;
Integer b=3;
a+=b;
System.out.println(a);
Integer is immutable, so what has happened above is 'a' has changed to a new reference of value 6. The initial value 3 is left with no reference in the memory (it has not been changed), so it can be garbage collected.
If this happens to a String, it will keep in the pool (in PermGen space) for longer period than the Integers as it expects to have references.
Yes Integer is immutable.
A is a reference which points to an object. When you run a += 3, that reassigns A to reference a new Integer object, with a different value.
You never modified the original object, rather you pointed the reference to a different object.
Read about the difference between objects and references here.
Immutable does not mean that you cannot change value for a variable. It just means that any new assignment creates a new object ( assigns it a new memory location) and then the value gets assigned to it.
To understand this for yourself, perform Integer assignment in a loop ( with integer declared outside the loop ) and look at the live objects in memory.
The reason why copy constructor is not needed for immutable objects is simple common sense. Since each assignment creates a new object, the language technically creates a copy already, so you do not have to create another copy.
This is how I understand immutable
int a=3;
int b=a;
b=b+5;
System.out.println(a); //this returns 3
System.out.println(b); //this returns 8
If int could mutate, "a" would print 8 but it does not because it is immutable, thats why it is 3. Your example is just a new assignment.
"Immutable classes do not need copy constructors". Anyone care to explain why?
The reason is that there is rarely any need to copy (or even any point in copying) an instance of a immutable class. The copy of the object should be "the same as" the original, and if it is the same, there should be no need to create it.
There are some underlying assumptions though:
It assumes that your application does not place any meaning on the object identity of instances of the class.
It assumes that the class has overloaded equals and hashCode so that a copy of an instance would be "the same as" the original ... according to these methods.
Either or both of those assumptions could be false, and that might warrant the addition of a copy constructor.
I can make clear that Integer (and other of its creed like Float, Short etc) are immutable by simple sample code:
Sample Code
public class Test{
public static void main(String... args){
Integer i = 100;
StringBuilder sb = new StringBuilder("Hi");
Test c = new Test();
c.doInteger(i);
c.doStringBuilder(sb);
System.out.println(sb.append(i)); //Expected result if Integer is mutable is Hi there 1000
}
private void doInteger(Integer i){
i=1000;
}
private void doStringBuilder(StringBuilder sb){
sb.append(" there");
}
}
Actual Result
The result comes to he Hi There 100 instead of expected result (in case of both sb and i being mutable objects) Hi There 1000
This shows the object created by i in main is not modified, whereas the sb is modified.
So StringBuilder demonstrated mutable behavior but not Integer.
So Integer is Immutable. Hence Proved
Another code without only Integer:
public class Test{
public static void main(String... args){
Integer i = 100;
Test c = new Test();
c.doInteger(i);
System.out.println(i); //Expected result is 1000 in case Integer is mutable
}
private void doInteger(Integer i){
i=1000;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
String s1="Hi";
String s2=s1;
s1="Bye";
System.out.println(s2); //Hi (if String was mutable output would be: Bye)
System.out.println(s1); //Bye
Integer i=1000;
Integer i2=i;
i=5000;
System.out.println(i2); // 1000
System.out.println(i); // 5000
int j=1000;
int j2=j;
j=5000;
System.out.println(j2); // 1000
System.out.println(j); // 5000
char c='a';
char b=c;
c='d';
System.out.println(c); // d
System.out.println(b); // a
}
Output is :
Hi
Bye
1000
5000
1000
5000
d
a
So char is mutable , String Integer and int are immutable.
Copy and run this code,I hope this will answer all your doubts
private static void wrapperClassDemo() {
//checking wrapper class immutability using valueOf method
//We can create wrapper class by using either "new" keyword or using a static method "valueOf()"
//The below Example clarifies the immutability concept of wrapper class in detail
//For better understanding just ciopy the below code to the editor and run
Integer num1 =Integer.valueOf(34); // i'm passing the 34 as the parameter to the valueOf method
System.out.println("value assigned to num1 is : "+num1);
System.out.println("Printing the hashcode assigned to store the \" num1 \"value in memory: "+System.identityHashCode(num1));
Integer num2 =Integer.valueOf(34);
System.out.println("value assigned to num2 is : "+num2);
System.out.println("Printing the hashcode assigned to store the \" num2 \"value in memory: "+System.identityHashCode(num2));
/*Now u can notice both the hashcode value of num1 and num2 are same. that is because once you created the num1 with the value 34 an object is
* created in the heap memory. And now You are passing the value same as num1 to the num2 .Now JVM Checks the same value is present in the heap Mmeomry
* If present the reference variable(in this example it is num2) will be pointed to the same address where the object num1 is stored so u get the same hashcode */
num2++; // You can use num2 = 35 as both are same;
System.out.println("\nvalue assigned to num2 is : "+num2);
System.out.println("Printing the hashcode of \" num1 \": "+System.identityHashCode(num1) + "\nPrinting the hashcode of \" num2 \": "+System.identityHashCode(num2));
System.out.println("As now you can notice the hashcode has changed for num2 ,That is because now a new object is created for num2 and it is referencing the new object");
//Again i'm incrementing num2
System.out.println("\nBefore incremeting the hashcode of \" num2 \" is: "+System.identityHashCode(num2));
num2++; // You can use num2 = 36 as both are same;
System.out.println("After incremeting the hashcode of \" num2 \" is: "+System.identityHashCode(num2));
//now the hashcode value of num2 is changed ,again new object is created for the updated value and num2 is referencing new object ,and old object will be garbage collected
System.out.println("\n Thus the CONCLUSION is Wrapper objects are immutable ,They only create new object and refernce the new object ,They won't modify the present object ");
System.out.println("This is applicable for Strings also");
Something to hold in mind is that there is now a cache for Integer values. It sometimes saves developers from the mistake of using == instead of .equals() when changing from int to Integer. Not always though. When you instantiate a new Integer, there will be a new instance created. So Integers are not only immutable, but also semi static.
Integer a = 3;
Integer b = 3;
Integer c = new Integer(3);
b = b + 1;
b = b - 1;
System.out.println("a-id: " + System.identityHashCode(a));
System.out.println("b-id: " + System.identityHashCode(b));
System.out.println("c-id: " + System.identityHashCode(c));
System.out.println("a == b: " + (a == b));
System.out.println("a == c: " + (a == c));
System.out.println("a eq c: " + (a.equals(c)));
Gives the printout:
a-id: 666988784
b-id: 666988784
c-id: 1414644648
a == b: true
a == c: false
a eq c: true
I want to use guava iterator or java8 foreach(may be lambda expression) nested for loop and process some statements and return a long variable. Here is my code in native java. Please excuse my code may not efficient. I read over net accessing non final variables inside new java 8 foreach is not possible.
Long x = Long.valueOf(0);
Long y = Long.valueOf(0);
for(FirstLevel first : Levels)
{
if(first.getSecondLevels() == null)
{
x= x + getSomeValue(first);
}
for (SecondLevel second : first.getSecondLevels())
{
y = y + getSomeValue(second);
}
}
return x + y;
I have tried but unable to return the values. Thanks in advance for help!
Couple things:
Before approaching "refactoring" like that one you ask, I really strongly recommend learning more "pure" Java (which I assume is the case here, #javalearner). For example you can use long literals instead of manually boxing values:
long x = 0L;
long y = 0L;
Anyway...
using Guava won't help here - this is the imperative way of doing it, and with Java 7 + Guava you'd have to write awkward anonymous classes (i.e. Functions), which without language support is painful. Which brings me to...
Java 8 and Streams. This is probably the best way to go, but first you have to fix (?) your code and define actual problem - for example this statement x= x + getSomeValue(x); evaluates x each time and does not take FirstLevel into account (same is true for y and SecondLevel), so I assume what you really meant was x =+ getSomeValue(firstLevel);.
Having all that said - please be more specific what your problem really is.
EDIT:
After your clarification, using streams your code could look like this:
final long sum = levels.stream()
.mapToLong(first -> getSomeValue(first) + first.getSecondLevels().stream().mapToLong(this::getSomeValue).sum())
.sum();
or with some helper method:
final long s = levels.stream()
.mapToLong(first -> getSomeValue(first) + getSecondLevelSum(first))
.sum();
private long getSecondLevelSum(final FirstLevel first) {
return first.getSecondLevels().stream().mapToLong(this::getSomeValue).sum();
}
First of all, there is no sense in using boxed Long values and even if you once need a boxed value, you don’t need to invoke Long.valueOf, Java already does that for you when converting a long primitive to a boxed Long object.
Further, since adding long values does not depend on the order of summands, there is no reason to maintain two variable throughout the operation, when you will add them at the end anyway:
long result=0;
for(FirstLevel first: Levels) {
result += getSomeValue(first);
for(SecondLevel second: first.getSecondLevels()) {
result += getSomeValue(second);
}
}
return result;
Note that the operator += does the same as result = result + … here, but avoids the repetition of the target operand.
Assuming that both, Levels and the result of getSecondLevels, are collections you can write the same as Stream operation as
return Levels.stream()
.mapToLong(first ->
getSomeValue(first) + first.getSecondLevels().stream()
.mapToLong(second -> getSomeValue(second)).sum())
.sum();
or, alternatively
return Levels.stream()
.flatMapToLong(first -> LongStream.concat(
LongStream.of(getSomeValue(first)),
first.getSecondLevels().stream().mapToLong(second -> getSomeValue(second))))
.sum();
If Levels is an array, you have to replace Levels.stream() with Arrays.stream(Levels) and likewise, if getSecondLevels() returns an array, you have to replace first.getSecondLevels().stream() with Arrays.stream(first.getSecondLevels())
I wrote some code to understand what would happen if I store a mixture of primitives, objects mutable or immutable into an Array object. Could I amend them after storage and see if it Dereferenced these things correctly and returned their amended values. I did not get what I had expected my code to do ? I think I know why and would like to clarify whether this understanding is correct. Here is the code.
public class DriverApp3 {
private static String CYEAR = "2014" ;
private static StringBuffer CYEARFLG = new StringBuffer("1914") ;
public double money = 2.13 ;
public static void main(String args[])
{
Integer j = 12 ;
DriverApp3 d = new DriverApp3();
StringBuffer sb = new StringBuffer("Unicorn");
MutableInteger mi = new MutableInteger(67);
int i = 76 ;
Object[] parseXML = new Object[]{j,DriverApp3.CYEAR,d, d.money,DriverApp3.CYEAR, sb, mi, DriverApp3.CYEARFLG,i};
// 0 1 2 3 4 5 6 7 8
System.out.println("======chng of all original values ==========");
j = 13 ;
d.money = 3.14 ;
parseXML[4]="2015";
DriverApp3.CYEAR = "2013";
mi.set(9);
sb.replace(3,5,"KO");
DriverApp3.CYEARFLG.replace(0,4,"1939");
i = 7 ;
Object[] chngdO = new Object[]{j,DriverApp3.CYEAR,d, d.money,DriverApp3.CYEAR, sb, mi, DriverApp3.CYEARFLG,i};
int cnt = 0 ;
for (Object m : parseXML)
{
Integer s_objid = m.hashCode();
String clsType = "Type="+m.getClass().getTypeName();
String clsName = "SimplName="+m.getClass().getSimpleName();
String canName = "CanonName="+m.getClass().getCanonicalName();
Object n = chngdO[cnt];
Integer ns_objid = n.hashCode();
String nclsType = "Type="+n.getClass().getTypeName();
String nclsName = "SimplName="+n.getClass().getSimpleName();
String ncanName = "CanonName="+n.getClass().getCanonicalName();
System.out.println(cnt + ": Hashcode=" + s_objid + ":" + clsType + ":" + m + "\n " + ": Hashcode=" + ns_objid + ":" + nclsType /*+ ":"+ clsName+ ":"+ canName*/+ ":" + n + "\n" );
cnt++ ;
}
}
#Override
public String toString()
{
return "Hashcode="+this.hashCode() + "," + DriverApp3.CYEAR ;
}
}
The mutable class is also here .....
/**
*
* #author code snippet from stackoverflow.com
* Not thread safe
*/
public class MutableInteger {
private int value;
public MutableInteger(int value) {
this.value = value;
}
public void set(int value) {
this.value = value;
}
public int intValue() {
return value;
}
public String toString()
{
return "id="+this.hashCode()+" val=" + this.value ;
}
}
The output of my application is .....
======chng of all original values ==========
0: Hashcode=12:Type=java.lang.Integer:12
: Hashcode=13:Type=java.lang.Integer:13
1: Hashcode=1537249:Type=java.lang.String:2014
: Hashcode=1537248:Type=java.lang.String:2013
2: Hashcode=366712642:Type=xander.DirRefOrCopy.DriverApp3:Hashcode=366712642,2013
: Hashcode=366712642:Type=xander.DirRefOrCopy.DriverApp3:Hashcode=366712642,2013
3: Hashcode=815979831:Type=java.lang.Double:2.13
: Hashcode=300063655:Type=java.lang.Double:3.14
4: Hashcode=1537250:Type=java.lang.String:2015
: Hashcode=1537248:Type=java.lang.String:2013
5: Hashcode=1829164700:Type=java.lang.StringBuffer:UniKOrn
: Hashcode=1829164700:Type=java.lang.StringBuffer:UniKOrn
6: Hashcode=2018699554:Type=xander.DirRefOrCopy.MutableInteger:id=2018699554 val=9
: Hashcode=2018699554:Type=xander.DirRefOrCopy.MutableInteger:id=2018699554 val=9
7: Hashcode=1311053135:Type=java.lang.StringBuffer:1939
: Hashcode=1311053135:Type=java.lang.StringBuffer:1939
8: Hashcode=76:Type=java.lang.Integer:76
: Hashcode=7:Type=java.lang.Integer:7
Index 0
For the Integer j, it is immutable, so as soon as I amend it outside the array the 0th one is still pointing to the one with value 12 since it is still alive on wherever Java keeps it's immutable single copy for that Integer. This is apparently an area where all runtime constants for each class or interface is kept. In this case it is the String literal area. The amended j is pointing to a new Immutable single copy of value 13. See Hashcodes differ as well.
Index 1
Same issue like above. Just because it is a member of DriverApp3 you would have expected to have amended itself but it does not because the array has stored an old value of the memory address String in wherever java stores the single copy of that immutable. Since, that address is still "alive" it keeps pointing to that memory address within the array. Very very unintuitive - not sure whether there are other patterns or languages that handle this better. It could be a source of error. Want to make sure you reflect your changes then - use MUTABLE objs within it instead of IMMUTABLE. Or, you have the additional thinking overhead of having to remember that Java might Autobox your primitive (if you were storing a primitive ) into an Object literal depending on whether it is a String, Integer, Double etc.
Index 2
Everything works as expected - it is pointing to the array. So, it continues to point to the same mutable object address when it was changed.
Index 3
Again the double gets Autoboxed into a immutable Double. So, it is the same issue like String and Integer because it is an Object Array. Surely, been like this since Java 1 - btw - I am using Java 8 compiler here.
Index 4
parseXML[4]="2015";
Well here we are directly overwriting the address with the address of the immutable String literal 2015
Index 5 & 6
StringBuffer and MutableInteger reflect amendments correctly because they still point to the same address. Java does not create a new copy because they are meant to mutable by the very nature of they have been defined.
Index 7
Reflects the changes because it is a mutable StringBuffer and not a shared immutable literal !!
Index 8
Suffers from the same issue of a primitive being autoboxed into a immutable shared single copy literal.
So, if you want the contents of your stored Array to reflect your amended changes outside of the array use Mutable Objects. And, beware of the trap of automatic Autoboxing into immutable Object literals.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is Java “pass-by-reference”?
I am trying to understand the difference between the 2 Java programs written below:
public class Swapping {
public static void main(String[] args) {
IntWrap i = new IntWrap(10);
IntWrap j = new IntWrap(20);
swap(i, j);
System.out.println("i " + i.i + ", j " + j.i);
}
public static void swap(IntWrap i , IntWrap j){
int x = i.i;
i.i = j.i;
j.i = x;
System.out.println("i " + i.i + ", j " + j.i);
}
}
public class IntWrap {
int i;
public IntWrap(int i){
this.i = i;
}
}
Output :
i 20, j 10
i 20, j 10
And second one:
public class Swapping {
public static void main(String[] args) {
Integer i = new Integer(10);
Integer j = new Integer(20);
swap(i, j);
System.out.println("i " + i + ", j " + j);
}
public static void swap(Integer i , Integer j){
Integer temp = new Integer(i);
i = j;
j = temp;
System.out.println("i " + i + ", j " + j);
}
}
Output :
i 20, j 10
i 10, j 20
I am not able to understand that I even though I am passing the Integer object, it should get swapped in the original program. What difference did it created if I wrote the wrapper class on the top of it as I am again passing the object only.
All method parameters, including object references, are passed by value in Java. You can assign any value to the method parameter - the original value in the calling code will not be modified. However you can modify the passed object itself and the changes will persist when the method returns.
There are old Holder classes in J2SE API, specially designed to support calls to methods with "returnable parameters" (IntHolder or StringHolder, for instance). They are mostly used with generated code from IDL language as IDL requires support for in, out and inout parameters. These holders are very uncommon in other code.
You can also simulate passing by reference by using arrays:
String [] a = new String[1]; String [] b = new String[1];
void swap(String [] a, String [] b) {
String t = a[0]; a[0] = b[0]; b[0] = t;
}
Java uses call-by-value to pass all arguments.When you pass the object to a function, the object reference(address of object) gets passed by value.In the second program swap, you are assigning i=j and j=temp.
So i=address of 20
j=address of 10(new object)
But after return from swap, in the main program i is still pointing to 10 and j is pointing to 20.Thats why you are getting 10 and 20 back in main program.
But in first program, you are passing the address of your objects to swap function and in the swap function you are modifying the content of object pointed by these addresses.That is why, it is getting reflected in main method.
Ups. Integer objects are immutable in Java. You can not change their internal values neither from other method, neither at all. Only create new Integer object.
(If you don't know about pointers and references I suggest you go over them a bit, then the world will make more sense - Intro to Pointers)
Putting it down to the most simplest explanation, there are 2 ways java passed everything back and forth:
Pass-by=Value: Used for immutable objects (String, Integer, Double, etc.). These values cannot change with one exception, if you recreate the object.
String x = "World"; <- String x = new String("World");
x = "Hello"; <- x = new String("Hello");
x = x + " World"; <- x = new String("Hello" + " World");
printOutString(x); <- printOutString("Hello World");
Held at one memory location. Any alteration creates a new object with no relation to the previous and look at a separate memory location.
Pass-by-reference: Used for non-immutable objects (Classes, int, double, etc.). These values can be changed and still keep their old place in memory.
int i = 1;
i = 2; <- value at <reference-to-memory-as-value> = 2;
i = i + 1; <- value at <reference-to-memory-as-value> + 1;
printOutInteger(i); <- printOutInteger(value at <reference-to-memory-as-value>);
Any change to this object is done to the memory location. Therefore the location never changes (unless you create a new object).
The same is happening in your programs. The objects that say one thing in the method, then revert to the previous values. You are, in a way, Operator Overloading. You assign new values to the objections (Integer in this case) that you are sending, BUT you have passed the values which means Integer i within the method, because Integer is immutable, is looking at a different memory location to the Integer i in the main method. Therefore, when the method exits, the objects you passed are disposed of and Integer i and j now look at their original memory locations.
When you passed the classes with the int objects, as they are NOT immutable the memory locations were passed (by value) and the values at those locations were worked with. That is why the changes here were shown in the original objects.
I hope this helps
Here is a java line of code that i have failed to understand.
String line = "Some data";//I understand this line
int size;//I understand this line too
size = Integer.valueOf(line,16).intValue();//Don't understand this one
What i know is Integer.ValueOf(line) is the same as Integer.parseInt(line) , is not so? Correct me if i am wrong; Thanks.
Integer.ValueOf(line,16) converts string value line into an Integer object. In this case radix is 16.
intValue() gets the int value from the Integer object created above.
Furthermore, above two steps are equivalent to Integer.parseInt(line,16).
In order to get more INFO please refer Java API Documentation of Integer class.
Yes, this is equivalent to:
size = Integer.parseInt(line, 16);
Indeed, looking at the implementation, the existing code is actually implemented as effectively:
size = Integer.valueOf(Integer.parseInt(line, 16)).intValue();
which is clearly pointless.
The assignment to -1 in the previous line is pointless, by the way. It would only be relevant if you could still read the value if an exception were thrown by Integer.parseInt, but as the scope of size is the same block as the call to Integer.valueof, it won't be in scope after an exception anyway.
Please look at the data type of the variables on the left hand side.
public class Test {
public static void main(String[] args) {
String s = "CAFE";
Integer m = Integer.valueOf(s, 16);
int n = m.intValue();
System.out.println(n);
}
}
Integer is a reference type that wraps int, which is a primitive type.
" = Integer.valueOf().intValue()"
and Example:
String myNumber = "54";
int c = Integer.valueOf(myNumber).intValue(); // convert strings to numbers
result:
54 // like int (and before was a String)