Why Do People Still Use Primitive Types in Java

Why do people still use primitive types in Java?

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

why are there Primitive datatype in Java?

For efficiency. Variables of primitive types contain the value directly; variables of non-primitive types are references, referring to an object stored somewhere else in memory.

Each time you need to use the value of a wrapper type, the JVM needs to lookup the object in memory to get at the value. This isn't needed for primitive types, because the variable contains the value itself, instead of a reference to an object that contains the value.

However, that doesn't explain why primitive types need to be explicitly visible in the Java programming language. The designers of the Java language and the JVM could have chosen to hide primitive types from the language itself, so that you could treat everything as an object; the compiler could then translate it under the covers to more efficient primitive types.

Some newer programming languages that run on the JVM (Groovy, Scala and others) let you do exactly that: in the language itself everything looks like an object, which you can for example call methods on, but below the covers the compiler translates them to primitives.

I guess that in the time the Java language was developed (in the first half of the 1990's) people didn't think of that, and now it's too late for a radical change in the language to allow this.

Should I never use primitive types again?

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.

When to use primitive and when reference types in Java

In which case should you use primitive
types(int) or reference types
(Integer)?

As a rule of thumb, I will use a primitive (such as int) unless I have to use a class that wraps a primitive.

One of the cases were one must use a wrapper class such as Integer is in the case of using generics, as Java does not support the use of primitive types as type parameters:

List<int> intList = new ArrayList<int>();               // Not allowed.
List<Integer> integerList = new ArrayList<Integer>(); // Allowed.

And, in many cases, I will take advantage of autoboxing and unboxing, so I don't have to explicitly perform conversions from primitives to its wrapper class and vice versa:

// Autoboxing will turn "1", "2", "3" into Integers from ints.
List<Integer> numbers = Arrays.asList(1, 2, 3);

int sum = 0;

// Integers from the "numbers" List is unboxed into ints.
for (int number : numbers) {
sum += number;
}

Also, as an additional note, when converting from primitives to its wrapper class objects, and unique instances of objects are not necessary, use the valueOf method provided by the wrapper method, as it performs caching and return the same instance for a certain value, reducing the number of objects which are created:

Integer i1 = Integer.valueOf(1);   // Prefer this.
Integer i2 = new Integer(1); // Avoid if not necessary.

For more information on the valueOf methods, the API specification for the Integer.valueOf method can serve as a reference for how those methods will behave in the wrapper classes for primitives.

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

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

Why is it not possible use primitive types with polymorphic return types?

As always with these questions, the answer is that you'd have to ask the language designers. I can't see any reason why this couldn't be done. However in my opinion this feature would be fairly pointless. As you point out in the question it's only when moo is invoked on a variable of static type IntFoo that a primitive would get returned; on a variable of type Foo<Integer>, an Integer would get returned anyway. So you can achieve essentially the same thing by doing this.

public class IntFoo implements Foo<Integer> {

@Override
public Integer moo() { return mooAsInt(); }

public int mooAsInt() { return 0; }
}

Personally I think this is better because it's much more obvious when boxing does / does not take place. In your proposal, moo() could return an int or an Integer depending on the static type of the variable, which would be extremely confusing.

Is it a better practice to use Reference types or primitive types in Java?

Assuming you mean primitive wrapper types (Integer, Boolean, etc.) and not reference types in general: when you have a choice (often you don't: e.g. you are using API which requires one or the other, or you use them as generic type arguments, or you want to be nullable), prefer primitive types, because on the whole this will make your code simpler and faster.

Be careful if you need to switch from one to another, because == will still compile but give different results... usually.

When to use wrapper class and primitive type

Others have mentioned that certain constructs such as Collections require objects and that objects have more overhead than their primitive counterparts (memory & boxing).

Another consideration is:

It can be handy to initialize Objects to null or send null parameters into a method/constructor to indicate state or function. This can't be done with primitives.

Many programmers initialize numbers to 0 (default) or -1 to signify this, but depending on the scenario, this may be incorrect or misleading.

This will also set the scene for a NullPointerException when something is being used incorrectly, which is much more programmer-friendly than some arbitrary bug down the line.



Related Topics



Leave a reply



Submit