primitives vs wrapper class initialization - java

What is the Difference between declaring int's as Below. What are the cases which suits the usage of different Types
int i = 20;
Integer i = 20;
Integer i = new Integer(20);
Please Note : I have goggled and found that first is going to create primitive int.Second is going to carry out auto boxing and Third is going to create reference in memory.
I am looking for a Scenario which clearly explains when should I use first, second and third kind of integer initialization.Does interchanging the usage is going to have any performance hits
Thanks for Reply.

The initialization in the 1st case is a simple assignment of a constant value. Nothing interesting... except that this is a primitive value that is being assigned, and primitive values don't have "identity"; i.e. all "copies" of the int value 20 are the same.
The 2nd and 3rd cases are a bit more interesting. The 2nd form is using "boxing", and is actually equivalent to this:
Integer i = Integer.valueOf(20);
The valueOf method may create a new object, or it may return a reference to an object that existed previously. (In fact, the JLS guarantees that valueOf will cache the Integer values for numbers in the range -128..+127 ...)
By contrast new Integer(20) always creates a new object.
This issue with new object (or not) is important if you are in the habit of comparing Integer wrapper objects (or similar) using ==. In one case == may be true if you compare two instances of "20". In the other case, it is guaranteed to be false.
The lesson: use .equals(...) to compare wrapper types not ==.
On the question of which to use:
If i is int, use the first form.
If i is Integer, the second form is best ... unless you need an object that is != to other instances. Boxing (or explicitly calling valueOf) reduces the amount of object allocation for small values, and is a worthwhile optimization.

Primitives will take default values when declared without assignment.
But wrapper classes are reference types, so without assignment they will be null. This may cause a NullPointerException to be thrown if used without assignment.

One such scenario I can think of is when you are mapping DB types in Hibernate. If you use Integer you can check for null (assuming the column allows null values). If you use primitive and if the value is null in the database, I guess it throws an error.

Related

Memory of Integer

When I write:
Integer i = 5;
Integer i = new Integer(5);
Are these two lines equal?
In the memory the type i will be allocated in the heap as the same way in those two lines? And if yes, how all of this happens in the memory?
Are these two lines equal?
No.
The first line is the same as
Integer i = Integer.valueOf(5);
The compiler rewrites the code to that, which is known as autoboxing.
Refer to the Javadoc for Integer.valueOf:
If a new Integer instance is not required, this method should generally be used in preference to the constructor Integer(int), as this method is likely to yield significantly better space and time performance by caching frequently requested values. This method will always cache values in the range -128 to 127, inclusive, and may cache other values outside of this range.
So, Integer.valueOf(5) == Integer.valueOf(5) (it's the same instance returned each time) whereas new Integer(5) != new Integer(5) (a new instance is created each time).
But in all cases - as with all objects in Java - the Integer object is on the heap.
The Answer by Andy Turner is correct, and should be accepted. I can add a couple more thoughts and a diagram.
Integer constructor to be removed
Be aware that the constructors for all the primitive wrapper classes ( Integer, Long, Float, etc.) are not only deprecated, as of Java 16 & 17 they are marked for eventual removal. See JEP 390: Warnings for Value-Based Classes.
So, while interesting technically, this Question is moot practically.
new means new
To sum up Turner’s Answer: new means new. Calling the constructor via new always results in a new object being instantiated. This means a bit more memory taken to hold each new object.
Cache of Integer objects
The other two avenues, using a numeric literal or calling Integer.valueOf, may reuse an existing object cached by the JVM. Using a cache conserves memory.
Here is a decorated screenshot of a debugger showing the result of calling toString on each of these three approaches. We can see that x (numeric literal) and y (valueOf factory method) both point to the same object. Meanwhile, z (new constructor) points to a different object.
(The 42 & 7 were added for dramatic effect, to emphasize that the cache is a pool of possibly many objects. This actual code as shown would not have produced those objects.)

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

Why does int num = Integer.getInteger("123") throw NullPointerException?

The following code throws NullPointerException:
int num = Integer.getInteger("123");
Is my compiler invoking getInteger on null since it's static? That doesn't make any sense!
What's happening?
The Big Picture
There are two issues at play here:
Integer getInteger(String) doesn't do what you think it does
It returns null in this case
the assignment from Integer to int causes auto-unboxing
Since the Integer is null, NullPointerException is thrown
To parse (String) "123" to (int) 123, you can use e.g. int Integer.parseInt(String).
References
Java Language Guide/Autoboxing
Integer API references
static int parseInt(String)
static Integer getInteger(String)
On Integer.getInteger
Here's what the documentation have to say about what this method does:
public static Integer getInteger(String nm): Determines the integer value of the system property with the specified name. If there is no property with the specified name, if the specified name is empty or null, or if the property does not have the correct numeric format, then null is returned.
In other words, this method has nothing to do with parsing a String to an int/Integer value, but rather, it has to do with System.getProperty method.
Admittedly this can be quite a surprise. It's unfortunate that the library has surprises like this, but it does teach you a valuable lesson: always look up the documentation to confirm what a method does.
Coincindentally, a variation of this problem was featured in Return of the Puzzlers: Schlock and Awe (TS-5186), Josh Bloch and Neal Gafter's 2009 JavaOne Technical Session presentation. Here's the concluding slide:
The Moral
Strange and terrible methods lurk in libraries
Some have innocuous sounding names
If your code misbehaves
Make sure you're calling the right methods
Read the library documentation
For API designers
Don't violate the principle of least astonishment
Don't violate the abstraction hierarchy
Don't use similar names for wildly different behaviors
For completeness, there are also these methods that are analogous to Integer.getInteger:
Boolean.getBoolean(String)
Long.getLong(String)
Related questions
Most Astonishing Violation of the Principle of Least Astonishment
Most awkward/misleading method in Java Base API ?
On autounboxing
The other issue, of course, is how the NullPointerException gets thrown. To focus on this issue, we can simplify the snippet as follows:
Integer someInteger = null;
int num = someInteger; // throws NullPointerException!!!
Here's a quote from Effective Java 2nd Edition, Item 49: Prefer primitive types to boxed primitives:
In summary, use primitives in preference to boxed primitive whenever you have the choice. Primitive types are simpler and faster. If you must use boxed primitives, be careful! Autoboxing reduces the verbosity, but not the danger, of using boxed primitives. When your program compares two boxed primitives with the == operator, it does an identity comparison, which is almost certainly not what you want. When your program does mixed-type computations involving boxed and unboxed primitives, it does unboxing, and when your program does unboxing, it can throw NullPointerException. Finally, when your program boxes primitive values, it can result in costly and unnecessary object creations.
There are places where you have no choice but to use boxed primitives, e.g. generics, but otherwise you should seriously consider if a decision to use boxed primitives is justified.
Related questions
What is the difference between an int and an Integer in Java/C#?
Why does autoboxing in Java allow me to have 3 possible values for a boolean?
Is it guaranteed that new Integer(i) == i in Java? (YES!!!)
When comparing two Integers in Java does auto-unboxing occur? (NO!!!)
Java noob: generics over objects only? (yes, unfortunately)
From http://konigsberg.blogspot.com/2008/04/integergetinteger-are-you-kidding-me.html:
getInteger 'Determines the integer value of the system property with the specified name.'
You want this:
Integer.parseInt("123")
Please check documentation of the method getInteger().
In this method, the String parameter is a system property that determines the integer value of the system property with the specified name. "123" is not the name of any system property, as discussed here.
If you want to convert this String to int, then use the method as
int num = Integer.parseInt("123").

Why does autoboxing in Java allow me to have 3 possible values for a boolean?

Reference: http://java.sun.com/j2se/1.5.0/docs/guide/language/autoboxing.html
"If your program tries to autounbox null, it will throw a NullPointerException."
javac will give you a compile-time error if you try to assign null to a boolean. makes sense. assigning null to a Boolean is a-ok though. also makes sense, i guess.
but let's think about the fact that you'll get a NPE when trying to autounbox null. what this means is that you can't safely perform boolean operations on Booleans without null-checking or exception handling. same goes for doing math operations on an Integer.
for a long time, i was a fan of autoboxing in java1.5+ because I thought it got java closer to be truly object-oriented. but, after running into this problem last night, i gotta say that i think this sucks. the compiler giving me an error when I'm trying to do stuff with an uninitialized primitive is a good thing. I dont want to use autoboxing if I lose that.
I think I may be misunderstanding the point of autoboxing, but at the same time I will never accept that a boolean should be able to have 3 values. can anyone explain this? what am i not getting?
Boxed types are reference types, and all reference types, primitive boxes or not, can refer to null. That's why a Boolean can refer to null. So can an Integer. So can a String, etc.
Boxed types are not designed to make Java truly object oriented. Java will never be a purely object oriented language, and you should not code as if this is the case. Primitive types will never go away, and in fact should be preferred whenever there's a choice.
Here's a quote from Effective Java 2nd Edition, Item 49: Prefer primitive types to boxed primitives (emphasis by author):
In summary, use primitives in preference to boxed primitive whenever you have the choice. Primitive types are simpler and faster. If you must use boxed primitives, be careful! Autoboxing reduces the verbosity, but not the danger, of using boxed primitives. When your program compares two boxed primitives with the == operator, it does an identity comparison, which is almost certainly not what you want. When your program does mixed-type computations involving boxed and unboxed primitives, it does unboxing, and when your program does unboxing, it can throw NullPointerException. Finally, when your program boxes primitive values, it can result in costly and unnecessary object creations.
I've seen at least one case where the null value is useful. Lots of data objects in webservices have nullable boolean fields. Sometimes the user neglects to include a value. In this case you want to be able to discern the lack of a value from a default value. Previously, people would write getX, setX, and isXSet() methods, where isXSet returns false until someone calls setX. Now it's possible to make X be a nullable type and it's clear that it wasn't set if getX returns null.
In addition to everything said here, there are cases where you would very much want to have a third value for booleans - the case of an "optional" property.
We usually encounter it with databases, with boolean columns that allow nulls. Without using Booleans, we would need to use two separate variables, one indicating the value and another whether it is valid.
In fact, if you look at the JDBC API, you can see an example of this problem, where columns get a default value if they are null (e.g., a 0 for numeric fields), and then you have to call "wasNull" to check whether it is a true 0 or a fake null!
Your issue is with autounboxing, not autoboxing. I think autounboxing is evil for more significant reasons:
Consider this:
Integer i = new Integer(1);
Integer i2 = new Integer(12);
System.out.println(i == 10 || i != i2);
One == unboxes and the other doesn't.
Unboxing on operators (as opposed to assignments) was a mistake in my view (given the above - it is just not Java). Boxing, however, is very nice.
I think it's more philosophical than technical question. When you transform primitive type to reference type you should be ready that reference types (i.e. objects) are nullable.
You can watch The Billion Dollars Mistake presentation where C.A.R. Hoare says that his introducing null references to oop (Algol 60) was a mistake.
Josh Bloch in Effective Java recommends to prefer primitive types where it's possible. But sometimes you do have to verify you Boolean variable against null.
There is actually no big difference to the days before Java 1.5 - the problem is not the boolean type (it still has two states) but the Boolean wrapper (which always had 3 states. Boolean.TRUE, Boolean.FALSE and null).
Every conversion from a Boolean object to the boolean primitive requires null checks, with or without autoboxing.
Autoboxing automatically transforms data types between intrinsic types and Object types.
Object types for Boolean can be Boolean.TRUE, Boolean.FALSE, or null. That's why you have to deal with the possible 3 values for a boolean.
In databases, it is common to have three states for a boolean type. Consider a record that tracks whether someone has passed a class. There's TRUE, for passing; FALSE for not passing, and NULL for "currently taking the class". Yes, it's odd, but not having a value is inherit in object oriented programming.
I too find autoboxing a bit distasteful, mainly because it is a feature where the compiler adds bytecode to handle the conversion process. In my opinion, this can lead to people forgetting about important details in the conversion process which might be better remembered (such as the null handling in your case). It is useful, but not nearly as useful as most other features of the Java language.
Personally, I wish that the intrinsics were implemented as lightweight objects instead of "built-in" types. There's a lot of times where the hybrid intrinsic / object type system gets in the way. That said, intrinsics were supposed to be there to improve performance, but it seems that if you must do a lot of intrinsic to Object marshalling, you can't enjoy the intrinsic-only performance boost.
It is the problem with autoboxing, just like Integer i = null;. Integer object can be null while a native int cannot be.
It was never intended, with the introduction of autoboxing, that it replace the primitives. In most places primitives are what you want. If you want to start using the reference types because "it got java closer to be truly object-oriented" then that's your call, but as you are discovering, there are disadvantages with that approach. Performance will be another issue.
Autoboxing (and autounboxing) is there to help with the transitions between code that uses primitives (the majority) and the code that has to use reference types (rare). Of the reference types, Boolean is undoubtedly the rarest, since its small number of instances mean it's almost never worth putting in a Collection.
In summary: if the reference types are causing you trouble, don't use them. But don't say 'autoboxing is bad" just because they turned out not to be helpful in your situation.

Should I never use primitive types again?

Mixing the use of primitive data types and their respective wrapper classes, in Java, can lead to a lot of bugs. The following example illustrates the issue:
int i = 4;
...
if (i == 10)
doStuff();
Later on you figure that you want the variable i to be either defined or undefined, so you change the above instantiation to:
Integer i = null;
Now the equality check fails.
Is it good Java practise to always use the primitive wrapper classes? It obviously would get some bugs out of the way early, but what are the downsides to this? Does it impact performance or the application's memory footprint? Are there any sneaky gotchas?
Using the boxed types does have both performance and memory issues.
When doing comparisons (eg (i == 10) ), java has to unbox the type before doing the comparison. Even using i.equals(TEN) uses a method call, which is costlier and (IMO) uglier than the == syntax.
Re memory, the object has to be stored on the heap (which also takes a hit on performance) as well as storing the value itself.
A sneaky gotcha? i.equals(j) when i is null.
I always use the primitives, except when it may be null, but always check for null before comparison in those cases.
Firstly, switching from using a primitive to using an object just to get the ability to set it to null is probably a bad design decision. I often have arguments with my coworkers about whether or not null is a sentinel value, and my opinion is usually that it is not (and thus shouldn't be prohibited like sentinel values should be), but in this particular case you're going out of your way to use it as a sentinel value. Please don't. Create a boolean that indicates whether or not your integer is valid, or create a new type that wraps the boolean and integer together.
Usually, when using newer versions of Java, I find I don't need to explicitly create or cast to the object versions of primitives because of the auto-boxing support that was added some time in 1.5 (maybe 1.5 itself).
I'd suggest using primitives all the time unless you really have the concept of "null".
Yes, the VM does autoboxing and all that now, but it can lead to some really wierd cases where you'll get a null pointer exception at a line of code that you really don't expect, and you have to start doing null checks on every mathematical operation. You also can start getting some non-obvious behaviors if you start mixing types and getting wierd autoboxing behaviors.
For float/doubles you can treat NaN as null, but remember that NaN != NaN so you still need special checks like !Float.isNaN(x).
It would be really nice if there were collections that supported the primitive types instead of having to waste the time/overhead of boxing.
In your example, the if statement will be ok until you go over 127 (as Integer autoboxing will cache values up to 127 and return the same instance for each number up to this value)
So it is worse than you present it...
if( i == 10 )
will work as before, but
if( i == 128 )
will fail. It is for reasons like this that I always explicitly create objects when I need them, and tend to stick to primitive variables if at all possible
Thee java POD types are there for a reason. Besides the overhead, you can't do normal operations with objects. An Integer is an object, which need to be allocated and garbage collected. An int isn't.
If that value can be empty, you may find that in your design you are in need of something else.
There are two possibilities--either the value is just data (the code won't act any differently if it's filled in or not), or it's actually indicating that you have two different types of object here (the code acts differently if there is a value than a null)
If it's just data for display/storage, you might consider using a real DTO--one that doesn't have it as a first-class member at all. Those will generally have a way to check to see if a value has been set or not.
If you check for the null at some point, you may want to be using a subclass because when there is one difference, there are usually more. At least you want a better way to indicate your difference than "if primitiveIntValue == null", that doesn't really mean anything.
Don't switch to non-primitives just to get this facility. Use a boolean to indicate whether the value was set or not. If you don't like that solution and you know that your integers will be in some reasonable limit (or don't care about the occasional failure) use a specific value to indicate 'uninitialized', such as Integer.MIN_VALUE. But that's a much less safe solution than the boolean.
When you got to that 'Later on' point, a little more work needed to be accomplished during the refactoring. Use primitives when possible. (Capital period) Then make POJOs if more functionality is needed. The primitive wrapper classes, in my opinion, are best used for data that needs to travel across the wire, meaning networked apps. Allowing nulls as acceptable values causes headaches as a system 'grows'. To much code wasted, or missed, guarding what should be simple comparisons.

Categories

Resources