Java trie node Boolean vs boolean - java

I'm creating trie node class, which contains field with logical type and I don't know what will be better use boolean or Boolean.
I know that one instance of Boolean takes 16 Bytes and 4 bytes takes it reference in 32-bit VM. But Boolean have constants Boolean.TRUE and Boolean.FALSE, what can be used for space optimization. So application wiil takes 4*N+32 Bytes, where N is number of nodes, yes?
As far, as I know boolean value takes 4 bytes (in array it optimize to 1 byte per element) in 32-bit VM too)
However I can use code like this
boolean EOW = Boolean.TRUE;
but how many space it will take and how many time wiil take autboxing/inboxing?
So what will be better to use to optimize space usage and time?
And could you answer me how many space it tales on 64-bit VM?

Instead of this:
boolean EOW = Boolean.TRUE;
Just write this:
boolean EOW = true;
There is no reason to use Boolean.TRUE, it will be auto-unboxed to the primitive value true anyway, it's more efficient and less verbose to use the value true directly.
Only use wrapper classes such as Boolean when you have a good reason to do so - otherwise, use primitive types such as boolean. One reason to use a wrapper is when you need to store values in a collection (such as an ArrayList) - collection classes can only hold objects and not primitive values, so you'll have to use the wrapper class in that case.
Using Boolean objects is never more efficient than using boolean primitive values.
Note that primitive values are just values, not objects. If you use the value true ten times in your code, there will not be ten duplicate objects in memory.

Just use the primitive type boolean with true and false. Primitive types take less memory, work with better performance and are null-safe.

I expect the exact code, that you pasted, to be optimized to boolean EOW = true;, so it shouldn't be unboxed at all, but if there's no such an optimization, then you'll haven't any memory affected, because you use the static field, which will be initialized only once. Nevertheless, you still will lose one operation on imlicit running method booleanValue(), which will just return stored value. Actually, I don't have any idea, why you would want to have such an expression.

Related

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 is the difference between false and Boolean.FALSE?

In C++ windows.h FALSE is defined as integer which makes sense for some special logic cases, but in Java java.lang.Boolean.FALSE is defined as boolean and assigned to false
public static final Boolean FALSE and I've seen some people use it.
My question: is there a performance difference between false and Boolean.FALSE? in general why do people go and Boolean.FALSE?
See http://docs.oracle.com/javase/7/docs/api/java/lang/Boolean.html.
Boolean.TRUE and Boolean.FALSE are not boolean, they are Boolean. They are static instances of the two Boolean wrapper objects that correspond to the boolean values true and false.
Boolean is similar to an enum. The TRUE and FALSE instances are the instances returned by Boolean.valueOf().
As for performance of primitive vs. wrapper; there is no difference that you would ever need to be concerned about. The TRUE and FALSE static instances help performance a bit, and the javadocs recommend using Boolean.valueOf() as opposed to new Boolean(...) for that reason. The true and false boolean values are a little "lower level", but if you are storing them in a Boolean (as opposed to boolean) anyways it's irrelevant.
You should use whichever makes the most sense for your code and leads to the best readability (and definitely don't start going down the path of thinking of microoptimizations like primitive vs. wrapper types). If you are using a Boolean, use the object values. If you are using a boolean, use the primitive values. If you are deciding between Boolean vs boolean, use whatever is more appropriate (e.g. a Boolean can be null, which may be useful, and also you can't use primitive types for generic type parameters; on the other hand, a boolean can never be null which could be equally useful).
Also note that auto boxing converts the primitive types to one of those two static Boolean instances, e.g.:
Boolean a = true;
assert(a == Boolean.TRUE);
As an aside, since you mentioned it: FALSE is defined in windows.h for two reasons: 1) Because windows.h has been in use since C-only days, and C does not have a native bool type, and 2) it is traditional Microsoft practice to define data types and values with known, explicit sizes and values, esp. for passing data to Windows API functions across DLL boundaries (beyond the scope of this question) and for integrating with other languages that have different representations of "true" and "false". It is entirely unrelated to the reasons for Boolean.FALSE in Java.
false is a primitive and Boolean.FALSE is an object, so they're not really comparable.
If you assign false to a Boolean variable, like this:
Boolean b = false;
Java's auto boxing occurs to convert the primitive into an object, so the false value is lost and you end up with Boolean.FALSE anyway.
In terms of performance, using a primitive variable would slightly out-perform using a wrapper Boolean object, but your choice should be based on readability and basic design decisions rather than on "performance".
Boolean comes in handy when you need a tri-state variable.
Also, you might want to check out this autoboxing and unboxing tutorial, as well as the rules for how it works.
It is a very strange question, because false is the value of primitive type boolean, while Boolean.FALSE is a variable of reference type Boolean. Its value is reference to the object of type Boolean which internal boolean state is false.
In regards to performance, Boolean.FALSE will return a Boolean object, which might give you more flexibility to work with.
The primitive alternative takes up less memory
First of all, if you are unclear with this, you need to know that in Java numericals cannot be implicitly cast to booleans, e.g. you cannot compile something like:
int a = 1;
if(a){
//something, something
}
Second, some considerations about performance.
There's always a tradeoff.
When using primitive type boolean, performance should be better because you're using a value directly, which is either true or false (obviously, byte-encoded).
When using object type Boolean, a variable/field will hold a value, but that value cannot be immediately used, as that value is in fact the reference to an object, so you might have a performance penalty. Of course, this penalty is not significant in most cases. And, if you develop a time-critical application, most likely you are not using Java :). Nevertheless, using object types might bring some benefits in development process and safety in use cases implementation (e.g. it allows nulls, which is critical when you map JPA entities to relational tables and there are bit-typed columns that allow nulls; and this is only one scenario where object type is better).
In the end, be aware of boxing/un-boxing, which allows developers to use boolean-typed variables almost everywhere a Boolean-typed variable is expected (and the other way around).
Boolean is wrapper class for boolean primitive type, same as we have Integer for int.
Boolean has many methods to play around primitive type boolean
http://docs.oracle.com/javase/6/docs/api/java/lang/Boolean.html
Boolean a = null;
if (a) {
// NullPointerException
}
if (a != false) {
// NullPointerException
}
// Caution, comparing by reference, meaning 2 Booleans with same value could be different
if (a != Boolean.FALSE) {
System.out.println("But this one works");
}

Which statement (true or Boolean.TRUE) will be more efficient

My bean is as below
private boolean myBoolean;
public boolean isMyBoolean() {
return myBoolean;
}
public void setMyBoolean(
boolean myBoolean) {
this.myBoolean = myBoolean;
}
Now when I use setter for the above Boolean field then what should be the efficient way to do it
setMyBoolean(true);
or
setMyBoolean(Boolean.TRUE);
I know that autoboxing will take care and both will work But I don't know what is the efficient way in this example. So my question is which of both should I use to write an efficient code OR both are equally good
TIA
Use the first one. More readable. You don't need to concern about the performance issue here, although the second one will involve auto-boxing and comparatively slower (again, you don't need to think about it).
Only consider code readability in this type of cases, and remember that primitives will always be faster than objects.
imho
setMyBoolean(true);
Primitives always do favor than Wrappers.Where ever I am able to use primitives,I go for them
Because while run time, If we use Wrappers Boxing conversions and Unboxing Conversions happens at Runtime,Obviously that takes more time.
In your case
At run time, boxing conversion proceeds as follows:
If p is a value of type boolean, then boxing conversion converts p into a reference r of class and type Boolean, such that r.booleanValue() == p
If you use primitive there,Obviously you save that time.
The reason
boolean boolVar = Boolean.TRUE;
works is because of autounboxing, a Java 5 feature that allows a wrapper object to be converted to its primitive equivalent automatically when needed
as you can understand, setting is faster then autounboxing and then setting...
It does not matter. At the very end when your code is compiled the bytecode generated will end up using the boolean data type on the JVM.
What I am trying to say is, on compile time, such a simple code like this will be optimized automatically for the JVM. It does not matter which way you use, remember that the compiler will end up translating this into bytecode and JVMs nowadays do this kind of optimizations all the time.
If you are skeptical on this, you can try both ways and use a profiler on your code. You will be amazed.
Boolean.TRUE is a wrapper object for boolean.
Boolean class implementation from Sun SDK:
public final class Boolean ...
{
private final boolean value;
public static final Boolean TRUE = new Boolean(true);
public static final Boolean FALSE = new Boolean(false);
...
}
when you use setMyBoolean(Boolean.TRUE);:
VM creates Boolean object (in heap) and the saves the value to true.
Unboxes the created object and finally assigns primitive true to myboolean.
when you use setMyBoolean(true);: only step 2 will be performed from above. Thus faster!

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

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