There are instances where a method expects a primitive type double and you pass a Double object as a parameter.
Since the compiler unboxes the passed object will this increase memory usage or decrease performance?
This is what Java Notes says on autoboxing:
Prefer primitive types
Use the primitive types where there is no need for objects for two
reasons.
Primitive types may be a lot faster than the corresponding wrapper
types, and are never slower.
The immutability (can't be changed after creation) of the wrapper
types may make their use impossible.
There can be some unexpected behavior involving == (compare
references) and .equals() (compare values). See the reference below
for examples.
The rule of thumb is: always use primitives if possible.
There are cases where this is not possible, like collections, so use wrappers only then.
It's a design-choice and not trivially answered for every case.
There are several items that could influence your decision:
Advantages:
Auto-boxing and auto-unboxing can make your code easier to read:
Leaving out all the unnecessary .doubleValue() and Double.valueOf() reduces the visual noise and can make your code easier to read.
Auto-boxing allows you to easily use collections of primitive values (such as a List<Double>, ...)
Disadvantages:
excessive, unnecessary auto-boxing and auto-unboxing can hinder your performance.
For example, if you have an API that returns a double and another API that expects a double, but you handle the value as a Double in between, then you're doing useless auto-boxing.
auto-unboxing can introduce a NullPointerException where you don't expect it:
public void frobnicate(Double d) {
double result = d / 2;
// ...
}
using collections of auto-boxed values uses a lot more memory than a comparable double[] for example.
You don't have to avoid autoboxing if talking about performance, JVM should handle that. The only thing you should consider is a readability of your code.
Autoboxing should be avoided. It can lead to errors because of overloading and it has some performance impact.
Nonetheless it may not be an issue in your application. But be aware of the impact.
Related
I have read that primitive data types are faster than their classes and take less memory, but what about autoboxing? They will also wrapped to the wrapper classes as an object, then what is the benefit to use primitives?
You shouldn't expect auto-boxing to be any more efficient than the round trip of box_type.valueOf(value) where box_type is the relevant type(*).
The main burden of autoboxing is creating and destroying objects. Generational Garbage Collectors are built for that scenario but can still get overwhelmed.
Indeed if values are being put in containers frequently it may be more effective to hold boxed values in situations where a primitive is sufficient (e.g. a class field) to reduce the number of autoboxing steps that take place.
That is, don't think of boxed values as slow. Think of boxing (auto or otherwise) as a small overhead that could be significant at very large volumes.
(*) It could be less efficient but that would seem unlikely on any serious platform. However there's no guarantee that box_type.valueOf(value) is ever more efficient than new box_type(value) plus eventual clean-up.
Autoboxing doesn't happen unless it's necessary.
To make your rule complete, you should add something like "avoid writing code that makes autoboxing necessary when that can be avoided."
As a primitive version of Optional*, Java 1.8 provides OptionalInt, OptionalLong and OptionalDouble.
But I cannot find the equivalent OptionalBoolean class.
Are there any technical reasons against having an OptionalBoolean?
*
An Optional may or may not have the presence of a value, is used as an alternative to null.
This quote explains the considerations behind having primitive streams. I'm assuming the same applied to primitive Optionals. In short, primitive streams (and probably Optionals as well) were created for performance reasons. They didn't create them for all 8 primitive types to reduce code duplication and interface pollution.
Quoting the words of Brian Goetz in the lambda mailing list:
More generally: the philosophy behind having specialized
primitive streams (e.g., IntStream) is fraught with nasty tradeoffs.
On the one hand, it's lots of ugly code duplication, interface
pollution, etc. On the other hand, any kind of arithmetic on boxed ops
sucks, and having no story for reducing over ints would be terrible.
So we're in a tough corner, and we're trying to not make it worse.
Trick #1 for not making it worse is: we're not doing all eight
primitive types. We're doing int, long, and double; all the others
could be simulated by these. Arguably we could get rid of int too, but
we don't think most Java developers are ready for that. Yes, there
will be calls for Character, and the answer is "stick it in an int."
(Each specialization is projected to ~100K to the JRE footprint.)
Trick #2 is: we're using primitive streams to expose things that are best done in the primitive domain (sorting, reduction) but not
trying to duplicate everything you can do in the boxed domain. For
example, there's no IntStream.into(), as Aleksey points out. (If there
were, the next question(s) would be "Where is IntCollection?
IntArrayList? IntConcurrentSkipListMap?) The intention is many streams
may start as reference streams and end up as primitive streams, but
not vice versa. That's OK, and that reduces the number of conversions
needed (e.g., no overload of map for int -> T, no specialization of
Function for int -> T, etc.)
And I should mention that I found that quote in the answer to this question.
boolean values are often abused as parameters. Effective Java 2nd edition warns against abuse of booleans. They often lead to badly readable code if they are not for actual boolean true/false arguments. Instead, Joshua Bloch - the writer - tries to convince people to use double valued enum's:
Prefer two-element enum types to boolean parameters. It makes your code easier to read and to write, especially if you're using an IDE that supports autocompletion. Also it makes it easy to add more options later.
Most OptionalBoolean instances would probably be used incorrectly. This is a good reason for not including one. But I cannot say - only Oracle can - if this is the reason why it is not in there.
Apart for the desire to reduce the magnitude of the combinatorial explosion of primitive type specialisation classes I suspect one major reason for the absence of an OptionalBoolean is that the advantage of such a class is much smaller than the advantage of specialisations for the numeric types.
The reason for why the advantage is smaller is that there are only two different values of the type boolean. Because of this, most of the time you only get two object of type Boolean. Those two are cached as Boolean.TRUE and Boolean.FALSE and reused in most cases, e.g. when booleans are auto-boxed. Numeric wrapper types have a number of cached objects for a small range of values, for other values a new object has to be allocated every time a primitive value is stored in a generic container such as Optional.
So an Optional<Boolean> object is almost as efficient as an OptionalBoolean would be since no new Boolean have to be allocated to put an unboxed boolean into it.
I could also be useful to have two cashed Optional<Boolean> available somewhere in the standard library, as Optional.TRUE/FALSE perhaps. I don't know the reason for why there isn't.
Just to be complete about that: There is indeed an OptionalBoolean in Java 8, but not where you would expect it: it is com.sun.javafx.scene.control.behavior.OptionalBoolean.
But, while JavaFX is nowadays a fixed component of Java, it is not advisable to use it outside of JavaFX stuff.
Apart from that, its interface is completely different from the ones you have in java.util.*.
I am confused about when to use primitive vs. non-primitive(?) types (i.e. int vs. Integer) in Java. I realize that in some places you can't use primitive types (for example when making use of generics). But what about in "normal" code? Is there a performance penalty for using non-primitive types? What about when working with Android?
***My question is very similar to this question, which was discovered by one of the posters below. The answers to the linked question give additional insights into this question, which are not covered below.
*** "non-primitive" types are officially referred to as reference types.
Short answer: An int is a number; an Integer is a pointer that can reference an object that contains a number. Using Integer for arithmetic involves more CPU cycles and consumes more memory. An int is not an object and cannot passed to any method that requires objects (just like what you said about Generics).
Non-primitive types are objects. They have to be dynamically allocated, garbage collected, and checked for null-ness (although some of these operations may get removed by an optimizing compiler). Reading their actual value requires loading from a pointer. Primitive types are values. They generally take up less space and are faster to access.
A good rule of thumb is, use primitive types unless you need polymorphism, in which case use the corresponding object.
There is a slight penalty for converting between the types (autoboxing). Also int will have a bit less overhead so I would always go with int if you can.
Also see this question: When to use primitive and when reference types in Java
In Java, int is a primitive data type, while Integer is a Wrapper class.
int, being a primitive data type has less flexibility. We can only store the binary value of an integer in it.
Since Integer is a wrapper class for int data type, it gives us more flexibility in storing, converting and manipulating integer data.
Integer is a class and thus it can call various in-built methods defined in the class. Variables of type Integer store references to Integer objects, just as with any other reference (object) type.
You can find a more detailed explanation here.
As an OO purist, you would likely shun the primitives altogether and damn the performance costs and lack of postfix operators. (Yes, there is a performance cost.) You may also adopt this approach simply from extensibility considerations as a designer (without necessarily being hung up on purity.)
As a practical matter (outside of theoretical and aesthetic questions), use the primitives everywhere you can and use the object version where you can't use primitives. (You already mentioned one such case. The language and APIs will drive this decision.)
As a performance freak, you would likely shun the object versions and you may not really care too deeply if you step on a few OO golden rules and sacrosanct no-goes: performance is king and you make your decisions accordingly.
I'd recommend option 2 as a good place to start until you develop your own dogmatic preferences! :)
My view: Using Integer as parameters or return values allows one thing that primitive ints don't allow: Using null. But is this a good idea? I think it rarely ever is.
As far as performance is concerned: The compiler will optimize your code to some degree, so that is most of the time not a real concern.
Actually here is a similar topic with little practical value.
As far as I understand, primitives perform better and should be used everywhere except for the cases where Object-related features (e.g. null check) are needed. Right?
Do not forget that, since creating a new wrapper for every boxing occurrence is quite expensive, especially considering it usually being used at a single scope of a method, Autoboxing uses a pool of common wrappers.
This is in fact an implementation of the flyweight design pattern. When a boxing occurs for a well-known value, instead of creating a new wrapper instance, a pre-created instance is fetched from a pool and returned.
One consequence is: it’s still not recommended to use autoboxing for scientific calculations. For example, the code d = a * b + c is using Integer classes for a, b, c and d, and the generated code is d.valueOf(a.intValue() * b.intValue() + c.intValue()). All these method invocations have their own overhead, so it’s usually recommended to use autoboxing when needed to store primitives in collections.
And even then, if you have a huge collection of Integer wrapping int, the overhead can implies longer execution times, up to 20 times longer, as reported in this article.
Jb adds this important comment:
Also Wrapper.valueOf(primitive) uses pool of wrappers. So prefer Integer.valueOf(5) to new Integer(5)
Primitives are faster when they are used, as objects need to be unboxed before use; thus there is an extra step for the VM to perform. For example, In order perform arithmetic on an Integer, it must first be converted to an int before the arithmetic can be performed.
In many business applications this probably rarely matters. But if you were writing something very numnber-crunching heavy like, say, a graphics transformation processor you are a lot more likely to care.
yes, primitives are faster than objects.
Since java 5 you can even mix primitives and objects without manually converting one to another.
The autoboxing mechanism takes care of just that.
this means that if you put a primitive in a collection, the compiler will not complain, and convert the primitive to an object implicitly.
If you need store primitives in collections you might use commons-primitives.
I prefer using primitives to wrappers, only place that absolutely needs to have wrappers are entity classes. Databases support nulls, so entities should too.
I once worked on project that used primitives (and homebrew ORM) in database access:
class Foo{
int xxx = -1;
...
}
And then you had:
void persist(Foo foo){
...
statement.setInt(15,foo.getXXX()==-1?null:foo.getXXX());
...
}
God it was evil.
I would say you should be worried about using primitives over wrappers only when you profile your application and see that the autoboxing is a performance or memory issue. In my experience memory becomes an issue before CPU cycles when talking about primitives vs wrapping objects.
I want to convert a primitive to a string, and I tried:
myInt.toString();
This fails with the error:
int cannot be dereferenced
Now, I get that primitives are not reference types (ie, not an Object) and so cannot have methods. However, Java 5 introduced autoboxing and unboxing (a la C#... which I never liked in C#, but that's beside the point). So with autoboxing, I would expect the above to convert myInt to an Integer and then call toString() on that.
Furthermore, I believe C# allows such a call, unless I remember incorrectly. Is this just an unfortunate shortcoming of Java's autoboxing/unboxing specification, or is there a good reason for this?
Java autoboxing/unboxing doesn't go to the extent to allow you to dereference a primitive, so your compiler prevents it. Your compiler still knows myInt as a primitive. There's a paper about this issue at jcp.org.
Autoboxing is mainly useful during assignment or parameter passing -- allowing you to pass a primitive as an object (or vice versa), or assign a primitive to an object (or vice versa).
So unfortunately, you would have to do it like this: (kudos Patrick, I switched to your way)
Integer.toString(myInt);
Ditto on what Justin said, but you should do this instead:
Integer.toString(myInt);
It saves an allocation or two and is more readable.
One other way to do it is to use:
String.valueOf(myInt);
This method is overloaded for every primitive type and Object. This way you don't even have to think about the type you're using. Implementations of the method will call the appropriate method of the given type for you, e.g. Integer.toString(myInt).
See http://java.sun.com/javase/6/docs/api/java/lang/String.html.
seems like a shortcoming of the
specification to me
There are more shortcomings and this is a subtle topic. Check this out:
public class methodOverloading{
public static void hello(Integer x){
System.out.println("Integer");
}
public static void hello(long x){
System.out.println("long");
}
public static void main(String[] args){
int i = 5;
hello(i);
}
}
Here "long" would be printed (haven't checked it myself), because the compiler choses widening over autoboxing. Be careful when using autoboxing or don't use it at all!
The valid syntax closest to your example is
((Integer) myInt).toString();
When the compiler finishes, that's equivalent to
Integer.valueOf(myInt).toString();
However, this doesn't perform as well as the conventional usage, String.valueOf(myInt), because, except in special cases, it creates a new Integer instance, then immediately throws it away, resulting in more unnecessary garbage. (A small range of integers are cached, and access by an array access.) Perhaps language designers wanted to discourage this usage for performance reasons.
Edit: I'd appreciate it if the downvoter(s) would comment about why this is not helpful.
As everyone has pointed out, autoboxing lets you simplify some code, but you cannot pretend that primitives are complex types.
Also interesting: "autoboxing is a compiler-level hack" in Java. Autoboxing is basically a strange kludge added onto Java. Check out this post for more details about how strange it is.
It would be helpful if Java defined certain static methods to operate on primitive types and built into the compiler some syntactic sugar so that
5.asInteger
would be equivalent to
some.magic.stuff.Integer.asInteger(5);
I don't think such a feature would cause incompatibility with any code that compiles under the current rules, and it would help reduce syntactic clutter in many cases. If Java were to autobox primitives that were dereferenced, people might assume that it was mapping the dereferencing syntax to static method calls (which is effectively what happens in .NET), and thus that operations written in that form were no more costly than would be the equivalent static method invocations. Adding a new language feature that would encourage people to write bad code (e.g. auto-boxing dereferenced primitives) doesn't seem like a good idea, though allowing dereferencing-style methods might be.
In C#, integers are neither reference types nor do they have to be boxed in order for ToString() to be called. They are considered objects in the Framework (as a ValueType, so they have value semantics), however. In the CLR, methods on primitives are called by "indirectly" loading them onto the stack (ldind).