Object type in java - java

I learnt that Java is not a 100% OOP language and that this is because of data types which are not objects. But according to me, int is of type Integer and Integer belongs to Number and Number belongs to Object. So java is a 100% OOP language. Am I correct?

No, int and Integer are different. Integer is a regular class, which as you know is a subclass of Number which itself is a subclass of Object. But int is a primitive type. It is not a class, so obviously not a subclass of anything; it has no methods or attributes, and generally there is nothing you can do with int itself, except declare variables of that type, e.g.
int x = 3;
Since int is not a class, the values of int variables are not objects. They have no methods or attributes or properties, and there's not much you can do with them except certain mathematical operations which are handled specially by the compiler.
Note that the Java compiler (recent versions) will automatically insert code to convert an int into an Integer, or vice-versa, where necessary. So it might look like they're the same thing when you write your program, but they are actually not. For instance, if you write
Integer y = 5;
javac translates that into
Integer y = Integer.valueOf(5);
Or
Map<Integer,Integer> m = ...;
m.put(4, 8);
int z = m.get(4);
becomes
Map<Integer,Integer> m = ...;
m.put(Integer.valueOf(4), Integer.valueOf(8));
int z = m.get(Integer.valueOf(4)).intValue();

To add to the previous answers (which I think may have missed the point a little) - yes, int and Integer are two completely different (but related) concepts - one is a primitive, the other an equivalent class. More importantly however, that distinction has absolutely no bearing whatsoever on whether Java is an object-oriented language.
Every single Java program uses objects at some point (even if it is just the String[] args parameter to your main method). As such, Java is unequivocally an object-oriented language, simply because it relies on classes as a primary means of program development. The fact that it supports non-object primative types has nothing to do with that at all.

int is not an object of the class Integer. In Java, not all the data types are objects.

Related

Should I use Primitive or Object for entity and models in Java?

As a beginner at Java, I am confused while choosing the variable types in entity or model classes. As mentioned on Java Primitives versus Objects, both of them have some pros and cons e.g. memory usage. However, I would like to know the general approach while creating entity or model classes. So, in this case, should I prefer Primitive or Object type for variables for long, boolean, int, etc. as shown below?
public class Student {
private Long id; // long ?
private String name;
private Boolean isGraduated; // boolean ?
private Integer age; // int ?
}
Default value of Long and Integer variable is null.
But default value of long and int is 0
Compare:
If you use Objects:
public class Student {
private Long id; // long ?
private String name;
private Boolean isGraduated; // boolean ?
private Integer age; // int ?
}
id => null
age => null
If you use primitives:
public class Student {
private long id; // long ?
private String name;
private Boolean isGraduated; // boolean ?
private int age; // int ?
}
id => 0
age => 0
In many scenarios having 0 as default value is confusing, so it makes sense to use Objects in this case. If object value is "null" you know for sure that the value was not initialized. But if primitive value is "0", then it is not clear: is it a default uninitialized value, or this value was initialized with "0".
I generally prefer using primitive types, unless I need explicit null-check
Either works
As you noted, primitives require less memory. But objects have advantages, especially in some situations where objects will be expected rather than primitives. And in some situations, a primitive may be expected, though auto-boxing generally handles that. The compiler will certainly alert you when encountering these situations.
And Skliar makes a valid point about primitives having default values while objects do not. Either might be an advantage depending on the coding situation.
Keep in mind that, for most of your work, you should not worry about this. Such worries are an example of premature optimization. You almost certainly have more important things to worry about.
For many common business apps, the memory usage is inconsequential. My own default is to use objects, for the convenience and the features. From what I have noticed over the years, usage seems fairly split with some folks tending towards primitives and some towards objects.
The only situation where I think twice about primitive-versus-object is where auto-boxing may be invoked when dealing with loops through much data. In such a case, a mere declaration of int versus Integer might make a significant impact by avoiding pointless boxing. But, again, do not worry excessively about this, as relying on auto-boxing is perfectly acceptable and is usually the best policy.
record
Java 16+ now offers the records feature. A record is a brief way to write a class whose main purpose is to communicate data transparently and immutably. You simply declare the member field types and names. The compiler implicitly generates the constructor, getters, equals & hashCode, and toString methods.
I mention records merely to say this handy new feature, likely to become very popular, supports both objects and primitives. So using records does not affect the object-versus-primitive decision.
Your example class would be:
public record Student( Long id , String name , Boolean isGraduated , Integer age ) {}
… or:
public record Student( long id , String name , boolean isGraduated , int age ) {}
Usage is the same as a conventional class.
Student alice = new Student( 101L , "Alice" , false , 33 ) ;
Blurring the difference
You should know that the Java team at Oracle, and related community, are interested in blurring the difference between primitives and objects. Of course, the trick is doing so while honoring the extreme backward-compatibility that is a hallmark of the Java platform.
Some of this work is being done as part of Project Valhalla, including the possible addition of value types to Java.
To learn more about possible future directions in this regard, see talks given by Brian Goetz of Oracle, and others. Use your favorite search engine to search for “Java JEP primitive”. You will find links to JEPs such as:
JEP 401: Primitive Objects (Preview) (updated 2021-05)
JEP 402: Unify the Basic Primitives with Objects (Preview) (updated 2021-05)
JEP 218: Generics over Primitive Types (updated 2017-10)
JEP 169: Value Objects (updated 2019-10)
As others have noted, you can use either approach.
As Basil Bourque notes, if you are using memory usage (or some other kind of runtime efficiency measure) as your reason for deciding ... this is most likely premature optimization. The chances are that the differences will be too small to matter.
So how should you decide?
That's up to you. But >>my<< rule is:
If the modelling tells you that you need to be able to represent "this field is not set" (or similar), then you can1 use (say) Integer rather than int ... and consider using null to represent the "not set" case.
When you need to use the type as a generic parameter (as in List<Integer>) you have no choice but to use the object type. (In current versions of Java.)
If you have no specific reasons to use the object type (e.g. Integer) use the primitive type (e.g. int). In other words, this is my default choice.
Why is >>my<< default choice to use the primitive types?
Because of things like this:
private Integer field; // defaults to null which may lead to an NPE
and
Integer a = ...
Integer b = ...
if (a == b) // MISTAKE
In other words, some aspects of primitive wrapper types are more susceptible to programmer error than their primitive type equivalents.
1 - The flip-side is that if you support "unset", it makes your code more complicated. If you use a nullable type to do this, then you have test for null and deal with it appropriately wherever you use the (bare) field. So, it is better to design your system so that an "unset" field is not possible.
I see no reason to use objects in your case, but also don't think that using them would greatly impact performance. Personally, if I did not have a specific reason to use objects — like for example the need for an ArrayList<Integer> or any other generic collection — I would use primitives.
Then again, if I did need a huge collection of integers I would work with arrays (e.g. int[]).
Edit: Someone in the comments asked why people prefer List<T> as opposed to traditional arrays. Collections such as ArrayList<T> are mutable and easy to work with. Compare adding an element to an ArrayList<T>:
List<MyClass> collection = new ArrayList<MyClass>();
collection.add(new MyClass());
...to adding an element to an array:
public static int[] addElement(int sourceArr[], int e)
{
int newArr[] = new int[sourceArr.length + 1];
for (int i = 0; i < sourceArr.length; i++)
{
newArr[i] = sourceArr[i];
}
newArr[newArr.length - 1] = e;
return newArr;
}
// ...
int arr[] = { 1, 2, 3 };
arr = addElement(arr, 4); // { 1, 2, 3, 4 }

int or Integer in java [duplicate]

This question already has answers here:
What is the difference between an int and an Integer in Java and C#?
(26 answers)
Closed 2 years ago.
I have seen many times in code that people use int or Integer to declare variable in beans. I know int is datatype and Integer is wrapper class.
My question is, in which condition int or Integer should be used and is there any advantage of either of them over another?
My question is, in which condition int or Integer should be used and is there any advantage of either of them over another?
Well, you should use the reference type Integer whenever you have to. Integer is nothing more than a boxed int. An Object with a single field containing the specified int value.
Consider this example
public class Ex {
int field1;
Integer field2;
public Ex(){}
}
In this case field1 will be initialized with the value 0 while field2 will be initialized with null. Depending on what the fields represent, both approaches might be advantageous. If field1 represents some kind of UUID, would you want it to be initialized with a zero value?
I wouldn't worry too much about the performance implications of Autoboxing. You can still optimize after you get your code running.
For more information take a look at the documentation
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Integer.html
You always use int, pretty much.
Integer should rarely be used; it is an intermediate type that the compiler takes care of for you. The one place where Integer is likely to appear is in generics, as int is simply not legal there. Here is an example:
List<Integer> indices = new ArrayList<Integer>();
int v = 10;
indices.add(v);
The above works: It compiles with no errors and does what you think it would (it adds '10' to a list of integer values).
Note that v is of type int, not Integer. That's the correct usage; you could write Integer here and the code works as well, but it wouldn't be particularly idiomatic java. Integer has no advantages over int, only disadvantages; the only time you'd use it, is if int is straight up illegal. Which is why I wrote List<Integer> and not List<int> as the latter is not legal java code (yet - give it a few versions and it may well be legal then, see Project Valhalla).
Note also that the compiler is silently converting your v here; if you look at the compiled code it is as if javac compiled indices.add(Integer.valueOf(v)) here. But that's fine, let the compiler do its thing. As a rule what the compiler emits and what hotspot optimizes are aligned; trust that what javac emits will be relatively efficient given the situation.
int is a primitive type, a value type for number literals.
it is used whenever and wherever you just want to do some basic arithmetical operation;
it is a value type, so it's stored in the Stack area of the memory, hence operations on it are much faster;
whenever it's needed, compiler implicitly and automatically casts back and forth (a.k.a Boxing and Unboxing) from int to Integer and vice versa;
Integer is a Class, which is a reference type and you instantiate an Object of that type.
you create an object of that class, which means, that you also have some methods and operations on that object;
any time you do some arithmetic operation on the instance of Integer, under the hood, it's still implemented by int primitives, and it's just wrapped into box/container;
it is a reference type / object, which is very important, as you can Serialize or Deserialize it;
it also has some very useful utility factory methods, like Integer.valueOf(..) for example, to parse the String as an integer;
it can be well used into declarations of the generic types and it, as a class, supports the hierarchy as well. For instance, it extends Number, and you can make use of this;
it is stored in the Heap area of the memory.
int is a primitive and Integer is an object .
From an memory footprint point of view , primitive consume less memory than object and also primitives are immutable (since they use pass by value ) .
Here is a good article on when to use what :
https://www.baeldung.com/java-primitives-vs-objects

what do we mean exactly when we say "ints are immutable"

I'm confused on the concept of "being immutable". Our professor is saying "ints are immutable! Strings are immutable" everyday, what does he mean by that exactly?
A more general question, how do we know if a data structure is immutable or not?
Thanks
Some of the other answers here are confusing mutability/immutability with value/reference semantics, so be careful...
Simply put, an entity is mutable if it may be modified after it's been created. In other words, its value may change over time.
First, a counterexample. A Java String object is immutable; there is no method that you can call on a String object that will change its value:
String a = "foo";
a.concat("bar");
System.out.println(a); // foo
You could do this instead:
String a = "foo";
a = a.concat("bar");
System.out.println(a); // foobar
but that works because concat() is creating a new String object, and the reference a is then repointed at it. There are now two String objects; the original has not changed (it's just lost forever). a is mutable, the underlying object isn't.
As for int variables; in C or Java, we can do this:
int x = 3;
x = 4; // Mutates x
x++; // Mutates x
How do we know these really mutate x, rather than simply creating a new integer "object" and "repointing" x at it? (Other than by the fact that the language assures us that primitive types are distinct from object types.) In C, we can somewhat prove it:
int x = 3;
int *p = x; // Pointer to original entity
x = 4;
printf("%d\n", *p); // 4
AFAIK, there is no equivalent approach in Java. So you could argue that the question of whether integer types are truly mutable in Java is irrelevant.
As for how we know whether a given type is immutable, very often we don't. At least, not without inspecting it, or simply believing a promise we've been told.
In Java, ensuring a user-defined type is immutable involves following a few simple rules (explained here). But it's still just a promise; the language doesn't enforce it.
Immutability (of an object or value, not a variable) usually means there's no way to do an in-place change of the value. (One that would propagate to other references to it.) This means that if you have something like the following:
String a = "foo";
There is no operation that you could perform on a that would change its value. I.e. you can't have a hypothetical method append() that would cause the following behaviour:
String a = "foo";
a.append("bar"); // a is not reassigned
System.out.println(a); // prints "foobar"
You can contrast this with mutable objects like collections:
int[] as = new String[] { "foo" };
as[0] = "bar"; // we're changing `as` in-place - not the Strings stored in it
System.out.println(as[0]); // prints "bar"
Primitive types are not a great choice of example for Java, since you can't have multiple references to them, and there's no way to demonstrate the distinction between a mutation and a reassignment.
It's awkward to talk about immutability of ints, because the idea of mutating something that isn't a container doesn't make sense to most of us. So let's talk about strings.
Here's a string, in Python:
s = "abc"
Strings are containers in the sense that they contain some number of individual characters: here a, b, and c. If I want to change the second character to a d, I might try:
s[1] = 'd'
Which will fail with a TypeError. We say strings are immutable in Python because there is no operation that will alter an existing string. Certainly there are plenty of operations that will perform some operation and create a new string, but existing strings are set in stone.
There are a couple advantages here. One is that it allows interning: sometimes when a string needs allocating (and at the discretion of the interpreter), CPython will notice that an identical string has already been allocated and just reuse the same str object. This is easiest when strings are immutable—otherwise, you'd have to do something about problems like this:
s = "abc"
t = "abc" # this reuses the same memory, as an optimization
s[0] = "x" # oops! now t has changed, too!
Interning is particularly useful in Python and similar languages that support runtime reflection: it has to know the name of every function and method at runtime, and a great many methods have builtin names like __init__ (the name of the constructor method), so reusing the same string object for all those identical names saves a good deal of wasted space.
The other advantage is in semantics: you can safely pass strings to arbitrary functions without worrying that they'll be changed in-place behind your back. Functional programmers appreciate this kind of thing.
The disadvantage, of course, is that doing a lot of work with very large strings requires reallocating and rebuilding those large strings many times over, instead of making small edits in-place.
Now, about ints. This is NOT an example of immutability:
x = 3
x = 4
This doesn't involve the actual objects at all; it only assigns a new value to the variable x.
Consider instead:
x = [1, 2, 3]
y = x
x[:] = [4, 5, 6]
print y # [4, 5, 6]
The x[:] = syntax is "slice notation" for replacing the entire contents of a list. Here, x and y are two names for the same list. So when you replace the contents of x, you also see the same effect in y, because... they both name the same list. (This is different from reference variables in other languages: you can assign a new value to either x or y without affecting the other.)
Consider this with numbers. If you could do some hypothetical operation like the above on plain numbers, this would happen:
x = 3
y = x
x[:] = 4
print y # hypothetically, 4
But you can't do that. You can't change the number an existing int represents. So we call them immutable.
Mutating an int is easy in Smalltalk:
3 become: 4
This would change the 3 to a 4, overwriting the memory that previously contained a 3. If ints are interned (as they can be in Python), this could even mean that everywhere 3 appears in your source code, it acts like the number 4.
In C, these distinctions aren't as meaningful, because variables are fixed blocks of memory rather than the transient labels of Python. So when you do this:
int x = 3;
x = 4;
It's hard to say definitively whether this is "mutating" an int. It does overwrite existing memory, but that's also just how C variable assignment works.
Anyway! Mutability is just about whether you're altering an existing object or replacing it with a new one. In Python and Java, you can't alter existing strings, and you can't "alter" numbers, so we call them immutable. You're free to change the contents of lists and arrays in-place without creating new ones, so they're mutable.
What is immutable is highly language-dependent, but an immutable object is simply an object that cannot be changed after it is created.
What this usually means is that:
int x = 4;
x = 5;//not 'allowed'
This is seen in languages where primitives, such as an int, can be immutable (such as functional languages like Scala).
Most objects in OOP are actually pointers to a place in memory. If that object is immutable that location in memory cannot have its contents changed. In the case of a String in Java, we see this happening:
String a = "Hello"; //points to some memory location, lets say '0x00001'
a = a + " World!"; //points to a new locations, lets say '0x00002'
System.out.println(a);//prints the contents of memory location '0x00002'
In this case, a actually points to an entirely different place in memory after line 2. What this means is that another thread with a different scope that has handed a would not see "Hello World!" but instead "Hello":
String a = "Hello";
startThread(a, " Hello!");//starts some thread and passes a to it
startThread(b, " World!");//starts another thread and passes a to it
...
public void methodInThread(String a, String b) {
a = a + b;
System.out.println(a);
}
These two threads will output the following, regardless of the order they're called in:
"Hello Hello!" //thread 1
"Hello World!" //thread 2
An object is considered immutable if its state cannot change after it is constructed.
source : http://docs.oracle.com/javase/tutorial/essential/concurrency/immutable.html
Typically it means you can't call a method on the type (int or whatever) that will change a
Sometimes people refer to value types as being immutable
//theres no way for this to be mutable but this is an example of a value type
int a = 5
int b = a;
b=9
a does not change unlike class types like
MyClass a = new MyClass
MyClass b = a
b.DoSomething()
//a is now changed
An immutable object is some thing that once instantiated can not be modified. If you have to modify, a new object will be created and pointed to the reference.
And ints are not immutable.
There are some classes in java which are immutable like String, All Wrapper Class ie. Integer, Float, Long etc.
For Example:
Integer i=5;
i=10;
i=15;
When Integer i=5, here a new Integer object is created, then in the 2nd, i=10 rather assigning this value 10 to previously created object, a another new object is created and assign to i, and 3rd i=15 , here again new object is created and again is assigned to i.
Note: don't be confused with int with Integer. int is primitive type and Integer is wrapper class. All primitives are mutable.
The concepts of mutability and immutability are only relevant for things to which code may hold a reference. If one holds a reference to something, and some immutable aspect of that thing's state is observed to have some value (or state), then as long as that reference exists, that aspect of the thing's state may always be observed to have the same value (state).
The String type in Java may reasonably be described as immutable, because code which has a reference to a string and observes that it contains the characters "Hello" may examine it at any time and will always observe that it contain those characters. By contrast, a Char[] might in one moment be observed to contain the letters "Hello" but at some later time be observed to contain the letters "Jello". Thus, a Char[] is considered mutable.
Because it is not possible to hold a direct reference to an int in Java, the concepts of mutability and immutability are not really applicable to that type. One can, however, hold a reference to an Integer, for which they are relevant. Any such reference that is observed to have a particular value will always have that same value. Thus, Integer is immutable. Note that while the concepts of mutability and immutability aren't really applicable to value types like int, they do share a useful aspect of immutable types: the state represented by a storage location (variable, field, or array element) of either a primitive type or an immutable type is guaranteed not to change except by overwriting that location with either a new value or a reference to a different immutable object.

Conversions of strings to Integer and to int

Given that String s has been declared, the following 5 lines of code produce the same result:
int i = Integer.valueOf(s);
int y = Integer.parseInt(s);
int j = Integer.valueOf(s).intValue();
Integer x = Integer.valueOf(s);
Integer k = Integer.valueOf(s).intValue();
Are there circumstances where each one would be the preferred code? It appears that int and Integer are interchangeable and that .intValue() is not needed.
If you require an int, use parseInt(), if you require an Integer use valueOf(). Although they're (sort of) interchangeable now, it still makes more sense to use the one that directly returns the data type that you require. (Historically, they weren't interchangeable at all, this was introduced with auto-boxing and unboxing in Java 5.)
The intValue() method you're using is just converting the Integer class type to the int primitive, so using that and valueOf() is the worst possible combination, you never want to use that. (Nothing bad will happen, it's just longer to read, performs slightly worse and is generally more superfluous.)
If you don't care or don't know, then I'd use parseInt(). Especially as a beginner, it's more common that you want the primitive type rather than the class type.
int and Integer are made to look interchangeable by the magic of auto-boxing and auto-unboxing: In many cases where you need one but have the other, the compiler automagically inserts the necessary code to convert them.
This is useful, but if you know about it, you can avoid it in many places which results in slightly faster code (because there's less conversion to do).
Integer.parseInt() returns an int, so you should use it if you need an int
Integer.valueOf() returns an Integer, so you should use it if you need an Integer
Integer.valueOf().intValue() first creates an Integer and then extracts the int value from it. There's no good reason to use this instead of a simple Integer.parseInt().
The decision between int and Integer is easy to do as well:
generally you'd want to use the primitive type (int), if possible
if you need an Object (for example, if you want to put your number in a Collection), then you need to use the wrapper type (Integer), as the primitive type can't be used here.
int and Integer are not interchangeable.Because of Autoboxing feature fron java 5 onwards, int to Integer conversion is taken care by jvm itself.But we should not use Integer class unnecessarily.Primitive data types are always faster.Wrapper classes should be used only required.

Why do people still use primitive types in Java?

Since Java 5, we've had boxing/unboxing of primitive types so that int is wrapped to be java.lang.Integer, and so and and so forth.
I see a lot of new Java projects lately (that definitely require a JRE of at least version 5, if not 6) that are using int rather than java.lang.Integer, though it's much more convenient to use the latter, as it has a few helper methods for converting to long values et al.
Why do some still use primitive types in Java? Is there any tangible benefit?
In Joshua Bloch's Effective Java, Item 5: "Avoid creating unnecessary objects", he posts the following code example:
public static void main(String[] args) {
Long sum = 0L; // uses Long, not long
for (long i = 0; i <= Integer.MAX_VALUE; i++) {
sum += i;
}
System.out.println(sum);
}
and it takes 43 seconds to run. Taking the Long into the primitive brings it down to 6.8 seconds... If that's any indication why we use primitives.
The lack of native value equality is also a concern (.equals() is fairly verbose compared to ==)
for biziclop:
class Biziclop {
public static void main(String[] args) {
System.out.println(new Integer(5) == new Integer(5));
System.out.println(new Integer(500) == new Integer(500));
System.out.println(Integer.valueOf(5) == Integer.valueOf(5));
System.out.println(Integer.valueOf(500) == Integer.valueOf(500));
}
}
Results in:
false
false
true
false
EDIT Why does (3) return true and (4) return false?
Because they are two different objects. The 256 integers closest to zero [-128; 127] are cached by the JVM, so they return the same object for those. Beyond that range, though, they aren't cached, so a new object is created. To make things more complicated, the JLS demands that at least 256 flyweights be cached. JVM implementers may add more if they desire, meaning this could run on a system where the nearest 1024 are cached and all of them return true... #awkward
Autounboxing can lead to hard to spot NPEs
Integer in = null;
...
...
int i = in; // NPE at runtime
In most situations the null assignment to in is a lot less obvious than above.
Boxed types have poorer performance and require more memory.
Primitive types:
int x = 1000;
int y = 1000;
Now evaluate:
x == y
It's true. Hardly surprising. Now try the boxed types:
Integer x = 1000;
Integer y = 1000;
Now evaluate:
x == y
It's false. Probably. Depends on the runtime. Is that reason enough?
Besides performance and memory issues, I'd like to come up with another issue: The List interface would be broken without int.
The problem is the overloaded remove() method (remove(int) vs. remove(Object)). remove(Integer) would always resolve to calling the latter, so you could not remove an element by index.
On the other hand, there is a pitfall when trying to add and remove an int:
final int i = 42;
final List<Integer> list = new ArrayList<Integer>();
list.add(i); // add(Object)
list.remove(i); // remove(int) - Ouch!
Can you really imagine a
for (int i=0; i<10000; i++) {
do something
}
loop with java.lang.Integer instead? A java.lang.Integer is immutable, so each increment round the loop would create a new java object on the heap, rather than just increment the int on the stack with a single JVM instruction. The performance would be diabolical.
I would really disagree that it's much mode convenient to use java.lang.Integer than int. On the contrary. Autoboxing means that you can use int where you would otherwise be forced to use Integer, and the java compiler takes care of inserting the code to create the new Integer object for you. Autoboxing is all about allowing you to use an int where an Integer is expected, with the compiler inserting the relevant object construction. It in no way removes or reduces the need for the int in the first place. With autoboxing you get the best of both worlds. You get an Integer created for you automatically when you need a heap based java object, and you get the speed and efficiency of an int when you are just doing arithmetic and local calculations.
Primitive types are much faster:
int i;
i++;
Integer (all Numbers and also a String) is an immutable type: once created it can not be changed. If i was Integer, than i++ would create a new Integer object - much more expensive in terms of memory and processor.
First and foremost, habit. If you've coded in Java for eight years, you accumulate a considerable amount of inertia. Why change if there is no compelling reason to do so? It's not as if using boxed primitives comes with any extra advantages.
The other reason is to assert that null is not a valid option. It would be pointless and misleading to declare the sum of two numbers or a loop variable as Integer.
There's the performance aspect of it too, while the performance difference isn't critical in many cases (though when it is, it's pretty bad), nobody likes to write code that could be written just as easily in a faster way we're already used to.
By the way, Smalltalk has only objects (no primitives), and yet they had optimized their small integers (using not all 32 bits, only 27 or such) to not allocate any heap space, but simply use a special bit pattern. Also other common objects (true, false, null) had special bit patterns here.
So, at least on 64-bit JVMs (with a 64 bit pointer namespace) it should be possible to not have any objects of Integer, Character, Byte, Short, Boolean, Float (and small Long) at all (apart from these created by explicit new ...()), only special bit patterns, which could be manipulated by the normal operators quite efficiently.
I can't believe no one has mentioned what I think is the most important reason:
"int" is so, so much easier to type than "Integer". I think people underestimate the importance of a concise syntax. Performance isn't really a reason to avoid them because most of the time when one is using numbers is in loop indexes, and incrementing and comparing those costs nothing in any non-trivial loop (whether you're using int or Integer).
The other given reason was that you can get NPEs but that's extremely easy to avoid with boxed types (and it is guaranteed to be avoided as long as you always initialize them to non-null values).
The other reason was that (new Long(1000))==(new Long(1000)) is false, but that's just another way of saying that ".equals" has no syntactic support for boxed types (unlike the operators <, >, =, etc), so we come back to the "simpler syntax" reason.
I think Steve Yegge's non-primitive loop example illustrates my point very well:
http://sites.google.com/site/steveyegge2/language-trickery-and-ejb
Think about this: how often do you use function types in languages that have good syntax for them (like any functional language, python, ruby, and even C) compared to java where you have to simulate them using interfaces such as Runnable and Callable and nameless classes.
Couple of reasons not to get rid of primitives:
Backwards compatability.
If it's eliminated, any old programs wouldn't even run.
JVM rewrite.
The entire JVM would have to be rewritten to support this new thing.
Larger memory footprint.
You'd need to store the value and the reference, which uses more memory. If you have a huge array of bytes, using byte's is significantly smaller than using Byte's.
Null pointer issues.
Declaring int i then doing stuff with i would result in no issues, but declaring Integer i and then doing the same would result in an NPE.
Equality issues.
Consider this code:
Integer i1 = 5;
Integer i2 = 5;
i1 == i2; // Currently would be false.
Would be false. Operators would have to be overloaded, and that would result in a major rewrite of stuff.
Slow
Object wrappers are significantly slower than their primitive counterparts.
Objects are much more heavyweight than primitive types, so primitive types are much more efficient than instances of wrapper classes.
Primitive types are very simple: for example an int is 32 bits and takes up exactly 32 bits in memory, and can be manipulated directly. An Integer object is a complete object, which (like any object) has to be stored on the heap, and can only be accessed via a reference (pointer) to it. It most likely also takes up more than 32 bits (4 bytes) of memory.
That said, the fact that Java has a distinction between primitive and non-primitive types is also a sign of age of the Java programming language. Newer programming languages don't have this distinction; the compiler of such a language is smart enough to figure out by itself if you're using simple values or more complex objects.
For example, in Scala there are no primitive types; there is a class Int for integers, and an Int is a real object (that you can methods on etc.). When the compiler compiles your code, it uses primitive ints behind the scenes, so using an Int is just as efficient as using a primitive int in Java.
In addition to what others have said, primitive local variables are not allocated from the heap, but instead on the stack. But objects are allocated from the heap and thus have to be garbage collected.
It's hard to know what kind of optimizations are going on under the covers.
For local use, when the compiler has enough information to make optimizations excluding the possibility of the null value, I expect the performance to be the same or similar.
However, arrays of primitives are apparently very different from collections of boxed primitives. This makes sense given that very few optimizations are possible deep within a collection.
Furthermore, Integer has a much higher logical overhead as compared with int: now you have to worry about about whether or not int a = b + c; throws an exception.
I'd use the primitives as much as possible and rely on the factory methods and autoboxing to give me the more semantically powerful boxed types when they are needed.
int loops = 100000000;
long start = System.currentTimeMillis();
for (Long l = new Long(0); l<loops;l++) {
//System.out.println("Long: "+l);
}
System.out.println("Milliseconds taken to loop '"+loops+"' times around Long: "+ (System.currentTimeMillis()- start));
start = System.currentTimeMillis();
for (long l = 0; l<loops;l++) {
//System.out.println("long: "+l);
}
System.out.println("Milliseconds taken to loop '"+loops+"' times around long: "+ (System.currentTimeMillis()- start));
Milliseconds taken to loop '100000000' times around Long: 468
Milliseconds taken to loop '100000000' times around long: 31
On a side note, I wouldn't mind seeing something like this find it's way into Java.
Integer loop1 = new Integer(0);
for (loop1.lessThan(1000)) {
...
}
Where the for loop automatically increments loop1 from 0 to 1000
or
Integer loop1 = new Integer(1000);
for (loop1.greaterThan(0)) {
...
}
Where the for loop automatically decrements loop1 1000 to 0.
Primitive types have many advantages:
Simpler code to write
Performance is better since you are not instantiating an object for the variable
Since they do not represent a reference to an object there is no need to check for nulls
Use primitive types unless you need to take advantage of the boxing features.
You need primitives for doing mathematical operations
Primitives takes less memory as answered above and better performing
You should ask why Class/Object type is required
Reason for having Object type is to make our life easier when we deal with Collections. Primitives cannot be added directly to List/Map rather you need to write a wrapper class. Readymade Integer kind of Classes helps you here plus it has many utility methods like Integer.pareseInt(str)
I agree with previous answers, using primitives wrapper objects can be expensive.
But, if performance is not critical in your application, you avoid overflows when using objects. For example:
long bigNumber = Integer.MAX_VALUE + 2;
The value of bigNumber is -2147483647, and you would expect it to be 2147483649. It's a bug in the code that would be fixed by doing:
long bigNumber = Integer.MAX_VALUE + 2l; // note that '2' is a long now (it is '2L').
And bigNumber would be 2147483649. These kind of bugs sometimes are easy to be missed and can lead to unknown behavior or vulnerabilities (see CWE-190).
If you use wrapper objects, the equivalent code won't compile.
Long bigNumber = Integer.MAX_VALUE + 2; // Not compiling
So it's easier to stop these kind of issues by using primitives wrapper objects.
Your question is so answered already, that I reply just to add a little bit more information not mentioned before.
Because JAVA performs all mathematical operations in primitive types. Consider this example:
public static int sumEven(List<Integer> li) {
int sum = 0;
for (Integer i: li)
if (i % 2 == 0)
sum += i;
return sum;
}
Here, reminder and unary plus operations can not be applied on Integer(Reference) type, compiler performs unboxing and do the operations.
So, make sure how many autoboxing and unboxing operations happen in java program. Since, It takes time to perform this operations.
Generally, it is better to keep arguments of type Reference and result of primitive type.
The primitive types are much faster and require much less memory. Therefore, we might want to prefer using them.
On the other hand, current Java language specification doesn’t allow usage of primitive types in the parameterized types (generics), in the Java collections or the Reflection API.
When our application needs collections with a big number of elements, we should consider using arrays with as more “economical” type as possible.
*For detailed info see the source: https://www.baeldung.com/java-primitives-vs-objects
To be brief: primitive types are faster and require less memory than boxed ones

Categories

Resources