Integer.classis, as you say, a reference to theClassobject for theIntegertype.int.classis, similarity, a reference to theClassobject for theinttype. You're right that this doesn't sound right; the primitives all have aClassobject as a special case. It's useful for reflection, if you want to tell the difference betweenfoo(Integer value)andfoo(int value).Integer.TYPEis just an alias forint.class
You can get a sense of this with a simple program:
public class IntClasses {
public static void main(String[] args) {
Class<Integer> a = int.class;
Class<Integer> b = Integer.TYPE;
Class<Integer> c = Integer.class;
System.out.println(System.identityHashCode(a));
System.out.println(System.identityHashCode(b));
System.out.println(System.identityHashCode(c));
}
}
Example output (it'll be different each time, but the first two will always be the same, and the third will virtually always be different):
366712642
366712642
1829164700
Answer from yshavit on Stack Overflowjava - Integer.class vs int.class - Stack Overflow
Why doesn't Integer have a setValue(int i), and is there a way of changing its value.
java - How can I pass an Integer class correctly by reference? - Stack Overflow
When to use int vs Integer ?
Integer.classis, as you say, a reference to theClassobject for theIntegertype.int.classis, similarity, a reference to theClassobject for theinttype. You're right that this doesn't sound right; the primitives all have aClassobject as a special case. It's useful for reflection, if you want to tell the difference betweenfoo(Integer value)andfoo(int value).Integer.TYPEis just an alias forint.class
You can get a sense of this with a simple program:
public class IntClasses {
public static void main(String[] args) {
Class<Integer> a = int.class;
Class<Integer> b = Integer.TYPE;
Class<Integer> c = Integer.class;
System.out.println(System.identityHashCode(a));
System.out.println(System.identityHashCode(b));
System.out.println(System.identityHashCode(c));
}
}
Example output (it'll be different each time, but the first two will always be the same, and the third will virtually always be different):
366712642
366712642
1829164700
From java.lang.Class.isPrimitive API
There are nine predefined Class objects to represent the eight primitive types and void. These are created by the Java Virtual Machine, and have the same names as the primitive types that they represent, namely boolean, byte, char, short, int, long, float, and double.
These objects may only be accessed via the following public static final variables java.lang.Boolean.TYPE, java.lang.Integer.TYPE etc
There are two problems:
- Java uses pass by value, not by reference. Changing the reference inside a method won't be reflected into the passed-in reference in the calling method.
- Integer is immutable. There's no such method like
Integer#set(i). You could otherwise just make use of it.
To get it to work, you need to reassign the return value of the inc() method.
integer = inc(integer);
To learn a bit more about passing by value, here's another example:
public static void main(String... args) {
String[] strings = new String[] { "foo", "bar" };
changeReference(strings);
System.out.println(Arrays.toString(strings)); // still [foo, bar]
changeValue(strings);
System.out.println(Arrays.toString(strings)); // [foo, foo]
}
public static void changeReference(String[] strings) {
strings = new String[] { "foo", "foo" };
}
public static void changeValue(String[] strings) {
strings[1] = "foo";
}
Good answers above explaining the actual question from the OP.
If anyone needs to pass around a number that needs to be globally updated, use the AtomicInteger() instead of creating the various wrapper classes suggested or relying on 3rd party libs.
The AtomicInteger() is of course mostly used for thread safe access but if the performance hit is no issue, why not use this built-in class. The added bonus is of course the obvious thread safety.
import java.util.concurrent.atomic.AtomicInteger
import java.util.*;
class Main {
public static void main(String args[]) {
Integer[] a = {1,2};
int[] b = {1,2};
System.out.println(Arrays.toString(a));
System.out.println(Arrays.toString(b));
}
}Hi all, trying to learn Java from python background and run into some trouble.
So I have read that Integer is the object class and int is the binary primitive, and that Java compiler is now able to convert between them when nesessary.
But when should I use the primitive vs the object ? Generally speaking, all I can think of right now is that we should always use the primitives unless we may need to cast to another type in the future so then use object ones.
values can be stored in an object only if you have called a field in the class or method.
This statement doesn't make any sense. I can't tell if it is wrong or right, it just... doesn't make sense.
it shouldn't be able to call its value field without instantiating an object since value isn't static. I just can't wrap my head around how this is even possible.
Javac sees that and goes: Hey, you're shoving a square peg (a constant of type int) into a round hole (an object typed variable) - this doesn't make sense. Except, explicitly called out in the Java Language Specification, if an int expression shows up in a place where int expressions should not be, but an Integer expression works fine, then 'apply autoboxing'.
'apply autoboxing' means: Assume the programmer meant to write: Integer.valueOf(the expression) instead of what they wrote.
Thus:
Integer x = 56;
Integer x = Integer.valueOf(56);
are identical. They are so identical, they produce the same bytecode. That call to valueOf is in your class file, no matter how you write it. Let's test:
> cat Test.java
class Test {
Integer x = 56;
}
> javac Test.java
(`javap` is part of java distributions and prints bytecode)
> javap -private -c Test
Compiled from "Test.java"
class Test {
java.lang.Integer x;
Test();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: bipush 56
7: invokestatic #7 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
10: putfield #13 // Field x:Ljava/lang/Integer;
13: return
}
Look at that - calls to the static method Integer.valueOf, even though Integer.valueOf appears exactly nowhere in our Test.java file.
So, how does Integer.valueOf work?
Essentially, it works like this:
package java.lang;
public class Integer {
private static final Integer[] CACHE = generateCache();
private final int value;
public Integer(int value) {
this.value = value;
}
private static Integer[] generateCache() {
for (int i = 0; i < 256; i++) {
CACHE[i - 128] = new Integer(i);
}
}
public static Integer valueOf(int v) {
if (v >= -128 && v < 128) return CACHE[i + 128];
return new Integer(v);
}
}
In other words, the Integer class pre-creates 256 integer objects, from -128 to +127 (why those values? Eh, cuz sun thought those would come up so often, it'd be worthwhile to cache them, 25 years ago). If you valueOf() with a value between -128 and +127 you get one of the caches. If you valueOf outside of it, you get a new object.
We can prove that too:
> cat Example.java
class Example {
public static void main(String[] args) {
Integer a = -100;
Integer b = -100;
Integer c = 200;
Integer d = 200;
System.out.println("a == b? " + (a == b));
System.out.println("c == d? " + (c == d));
System.out.println("ident-hash a: " + System.identityHashCode(a));
System.out.println("ident-hash b: " + System.identityHashCode(b));
System.out.println("ident-hash c: " + System.identityHashCode(c));
System.out.println("ident-hash d: " + System.identityHashCode(d));
}
}
> java Example.java
a == b? true
c == d? false
ident-hash a: 1880794513
ident-hash b: 1880794513
ident-hash c: 1991313236
ident-hash d: 736778932
This code shows that for -100, that Integer.valueOf call is returning the exact same object (== compares reference identity, i.e.: Is it the same object, when used on objects, it does not compare values. a and b are just pointing to the same object, whereas c and d are pointing at different objects that have the same values).
It's like a bunch of identical houses build in the suburbs someplace: a and b are like pieces of paper with the same address written on them, whereas c and d are like pieces of paper with a different address on each, but the two houses at these addresses look the same.
The language can and does make any exceptions it wants for object types that are built into the language. In short, you can do that in Java, because Java says you can.
Specifically, the conversion of a primitive value (int, long, etc) to one of the wrapper classes (Integer, Long, etc) is called 'autoboxing' and, like the name says, is performed automatically.
Why is this allowed? Because it's highly convenient for users. Along with automatic unboxing, it allows you to get quite close to treating wrapper classes like the primitive values they contain.
Some terminology: you only 'call' methods, not variables or fields. 'Call' means 'transfer control to'.
In classes like Integer, you don't even know what fields it has. All you know is that it can store an integral value in a certain range. Values can only be entered into an Integer by calling a constructor, or one of the static methods that will return an Integer.
Documentation for Integer, in case you haven't seen it. Note that there are no operations that 'change' the value of an Integer; we say it is 'immutable'. If you want a different value, you can only make a new Integer.